OLD | NEW |
---|---|
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 "content/browser/push_messaging/push_messaging_message_filter.h" | 5 #include "content/browser/push_messaging/push_messaging_message_filter.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 // Chrome currently does not support the Push API in incognito. | 47 // Chrome currently does not support the Push API in incognito. |
48 const char kIncognitoPushUnsupportedMessage[] = | 48 const char kIncognitoPushUnsupportedMessage[] = |
49 "Chrome currently does not support the Push API in incognito mode " | 49 "Chrome currently does not support the Push API in incognito mode " |
50 "(https://crbug.com/401439). There is deliberately no way to " | 50 "(https://crbug.com/401439). There is deliberately no way to " |
51 "feature-detect this, since incognito mode needs to be undetectable by " | 51 "feature-detect this, since incognito mode needs to be undetectable by " |
52 "websites."; | 52 "websites."; |
53 | 53 |
54 // These UMA methods are only called from IO thread, but it would be acceptable | 54 // These UMA methods are called from the IO and/or UI threads. Racey but ok, see |
55 // (even though slightly racy) to call them from UI thread as well, see | |
56 // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/FNzZRJtN2aw/Aw0CW AXJJ1kJ | 55 // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/FNzZRJtN2aw/Aw0CW AXJJ1kJ |
57 void RecordRegistrationStatus(PushRegistrationStatus status) { | 56 void RecordRegistrationStatus(PushRegistrationStatus status) { |
58 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || |
58 BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
59 UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus", status, | 59 UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus", status, |
60 PUSH_REGISTRATION_STATUS_LAST + 1); | 60 PUSH_REGISTRATION_STATUS_LAST + 1); |
61 } | 61 } |
62 | |
63 void RecordUnregistrationStatus(PushUnregistrationStatus status) { | 62 void RecordUnregistrationStatus(PushUnregistrationStatus status) { |
64 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 63 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
65 UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationStatus", status, | 64 UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationStatus", status, |
66 PUSH_UNREGISTRATION_STATUS_LAST + 1); | 65 PUSH_UNREGISTRATION_STATUS_LAST + 1); |
67 } | 66 } |
68 | |
69 void RecordGetRegistrationStatus(PushGetRegistrationStatus status) { | 67 void RecordGetRegistrationStatus(PushGetRegistrationStatus status) { |
70 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || |
69 BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
71 UMA_HISTOGRAM_ENUMERATION("PushMessaging.GetRegistrationStatus", status, | 70 UMA_HISTOGRAM_ENUMERATION("PushMessaging.GetRegistrationStatus", status, |
72 PUSH_GETREGISTRATION_STATUS_LAST + 1); | 71 PUSH_GETREGISTRATION_STATUS_LAST + 1); |
73 } | 72 } |
74 | 73 |
75 // Curries the |success| and |p256dh| parameters over to |callback| and | 74 void UnregisterCallbackToClosure(const base::Closure& closure, |
76 // posts a task to invoke |callback| on the IO thread. | 75 PushUnregistrationStatus status) { |
77 void ForwardEncryptionInfoToIOThreadProxy( | 76 DCHECK(!closure.is_null()); |
78 const PushMessagingService::EncryptionInfoCallback& callback, | 77 closure.Run(); |
79 bool success, | |
80 const std::vector<uint8_t>& p256dh, | |
81 const std::vector<uint8_t>& auth) { | |
82 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
83 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
84 base::Bind(callback, success, p256dh, auth)); | |
85 } | 78 } |
86 | 79 |
87 // Returns whether |sender_info| contains a valid application server key, that | 80 // Returns whether |sender_info| contains a valid application server key, that |
88 // is, a NIST P-256 public key in uncompressed format. | 81 // is, a NIST P-256 public key in uncompressed format. |
89 bool IsApplicationServerKey(const std::string& sender_info) { | 82 bool IsApplicationServerKey(const std::string& sender_info) { |
90 return sender_info.size() == 65 && sender_info[0] == 0x04; | 83 return sender_info.size() == 65 && sender_info[0] == 0x04; |
91 } | 84 } |
92 | 85 |
93 // Returns sender_info if non-empty, otherwise checks if stored_sender_id | 86 // Returns sender_info if non-empty, otherwise checks if stored_sender_id |
94 // may be used as a fallback and if so, returns stored_sender_id instead. | 87 // may be used as a fallback and if so, returns stored_sender_id instead. |
(...skipping 28 matching lines...) Expand all Loading... | |
123 }; | 116 }; |
124 | 117 |
125 // Inner core of this message filter which lives on the UI thread. | 118 // Inner core of this message filter which lives on the UI thread. |
126 class PushMessagingMessageFilter::Core { | 119 class PushMessagingMessageFilter::Core { |
127 public: | 120 public: |
128 Core(const base::WeakPtr<PushMessagingMessageFilter>& io_parent, | 121 Core(const base::WeakPtr<PushMessagingMessageFilter>& io_parent, |
129 int render_process_id); | 122 int render_process_id); |
130 | 123 |
131 // Public Register methods on UI thread -------------------------------------- | 124 // Public Register methods on UI thread -------------------------------------- |
132 | 125 |
126 // Callback called on UI thread. | |
127 void SubscribeDidGetInfoOnUI(const RegisterData& data, | |
128 const std::string& push_subscription_id, | |
129 const std::string& sender_id, | |
130 bool is_valid, | |
131 const std::vector<uint8_t>& p256dh, | |
132 const std::vector<uint8_t>& auth); | |
133 | |
133 // Called via PostTask from IO thread. | 134 // Called via PostTask from IO thread. |
134 void RegisterOnUI(const RegisterData& data); | 135 void RegisterOnUI(const RegisterData& data); |
135 | 136 |
136 // Public Unregister methods on UI thread ------------------------------------ | 137 // Public Unregister methods on UI thread ------------------------------------ |
137 | 138 |
138 // Called via PostTask from IO thread. | 139 // Called via PostTask from IO thread. |
139 void UnregisterFromService(int request_id, | 140 void UnregisterFromService(int request_id, |
140 int64_t service_worker_registration_id, | 141 int64_t service_worker_registration_id, |
141 const GURL& requesting_origin, | 142 const GURL& requesting_origin, |
142 const std::string& sender_id); | 143 const std::string& sender_id); |
143 | 144 |
145 // Public GetSubscription methods on UI thread ------------------------------- | |
146 | |
147 // Callback called on UI thread. | |
148 void GetSubscriptionDidGetInfoOnUI(int request_id, | |
149 const GURL& origin, | |
150 int64_t service_worker_registration_id, | |
151 const GURL& endpoint, | |
152 const std::string& sender_info, | |
153 bool is_valid, | |
154 const std::vector<uint8_t>& p256dh, | |
155 const std::vector<uint8_t>& auth); | |
156 | |
157 // Callback called on UI thread. | |
158 void GetSubscriptionDidUnsubscribe( | |
159 int request_id, | |
160 PushGetRegistrationStatus get_status, | |
161 PushUnregistrationStatus unsubscribe_status); | |
162 | |
144 // Public GetPermission methods on UI thread --------------------------------- | 163 // Public GetPermission methods on UI thread --------------------------------- |
145 | 164 |
146 // Called via PostTask from IO thread. | 165 // Called via PostTask from IO thread. |
147 void GetPermissionStatusOnUI(const GURL& requesting_origin, | 166 void GetPermissionStatusOnUI(const GURL& requesting_origin, |
148 bool user_visible, | 167 bool user_visible, |
149 int request_id); | 168 int request_id); |
150 | 169 |
151 // Public helper methods on UI thread ---------------------------------------- | 170 // Public helper methods on UI thread ---------------------------------------- |
152 | 171 |
153 // Called via PostTask from IO thread. The |io_thread_callback| callback | 172 // Called via PostTask from IO thread. |callback| will be run on UI thread. |
154 // will be invoked on the IO thread. | 173 void GetSubscriptionInfoOnUI( |
155 void GetEncryptionInfoOnUI( | |
156 const GURL& origin, | 174 const GURL& origin, |
157 int64_t service_worker_registration_id, | 175 int64_t service_worker_registration_id, |
158 const std::string& sender_id, | 176 const std::string& sender_id, |
159 const PushMessagingService::EncryptionInfoCallback& io_thread_callback); | 177 const std::string& push_subscription_id, |
178 const PushMessagingService::SubscriptionInfoCallback& callback); | |
160 | 179 |
161 // Called (directly) from both the UI and IO threads. | 180 // Called (directly) from both the UI and IO threads. |
162 bool is_incognito() const { return is_incognito_; } | 181 bool is_incognito() const { return is_incognito_; } |
163 | 182 |
164 // Returns a push messaging service. May return null. | 183 // Returns a push messaging service. May return null. |
165 PushMessagingService* service(); | 184 PushMessagingService* service(); |
166 | 185 |
186 // Returns a weak ptr. Must only be called from the outer class's constructor. | |
187 base::WeakPtr<Core> GetWeakPtrFromIOParentConstructor(); | |
188 | |
167 private: | 189 private: |
168 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; | 190 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; |
169 friend class base::DeleteHelper<Core>; | 191 friend class base::DeleteHelper<Core>; |
170 | 192 |
171 ~Core(); | 193 ~Core(); |
172 | 194 |
173 // Private Register methods on UI thread ------------------------------------- | 195 // Private Register methods on UI thread ------------------------------------- |
174 | 196 |
175 void DidRequestPermissionInIncognito(const RegisterData& data, | 197 void DidRequestPermissionInIncognito(const RegisterData& data, |
176 blink::mojom::PermissionStatus status); | 198 blink::mojom::PermissionStatus status); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 : BrowserMessageFilter(PushMessagingMsgStart), | 254 : BrowserMessageFilter(PushMessagingMsgStart), |
233 service_worker_context_(service_worker_context), | 255 service_worker_context_(service_worker_context), |
234 weak_factory_io_to_io_(this) { | 256 weak_factory_io_to_io_(this) { |
235 // Although this class is used only on the IO thread, it is constructed on UI. | 257 // Although this class is used only on the IO thread, it is constructed on UI. |
236 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 258 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
237 // Normally, it would be unsafe to obtain a weak pointer from the UI thread, | 259 // Normally, it would be unsafe to obtain a weak pointer from the UI thread, |
238 // but it's ok in the constructor since we can't be destroyed before our | 260 // but it's ok in the constructor since we can't be destroyed before our |
239 // constructor finishes. | 261 // constructor finishes. |
240 ui_core_.reset( | 262 ui_core_.reset( |
241 new Core(weak_factory_io_to_io_.GetWeakPtr(), render_process_id)); | 263 new Core(weak_factory_io_to_io_.GetWeakPtr(), render_process_id)); |
264 ui_core_weak_ptr_ = ui_core_->GetWeakPtrFromIOParentConstructor(); | |
242 | 265 |
243 PushMessagingService* service = ui_core_->service(); | 266 PushMessagingService* service = ui_core_->service(); |
244 service_available_ = !!service; | 267 service_available_ = !!service; |
245 | 268 |
246 if (service_available_) { | 269 if (service_available_) { |
247 default_endpoint_ = service->GetEndpoint(false /* standard_protocol */); | 270 default_endpoint_ = service->GetEndpoint(false /* standard_protocol */); |
248 web_push_protocol_endpoint_ = | 271 web_push_protocol_endpoint_ = |
249 service->GetEndpoint(true /* standard_protocol */); | 272 service->GetEndpoint(true /* standard_protocol */); |
250 } | 273 } |
251 } | 274 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 weak_factory_io_to_io_.GetWeakPtr(), data)); | 332 weak_factory_io_to_io_.GetWeakPtr(), data)); |
310 } | 333 } |
311 | 334 |
312 void PushMessagingMessageFilter::DidCheckForExistingRegistration( | 335 void PushMessagingMessageFilter::DidCheckForExistingRegistration( |
313 const RegisterData& data, | 336 const RegisterData& data, |
314 const std::vector<std::string>& push_registration_id_and_sender_id, | 337 const std::vector<std::string>& push_registration_id_and_sender_id, |
315 ServiceWorkerStatusCode service_worker_status) { | 338 ServiceWorkerStatusCode service_worker_status) { |
316 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 339 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
317 if (service_worker_status == SERVICE_WORKER_OK) { | 340 if (service_worker_status == SERVICE_WORKER_OK) { |
318 DCHECK_EQ(2u, push_registration_id_and_sender_id.size()); | 341 DCHECK_EQ(2u, push_registration_id_and_sender_id.size()); |
319 const auto& push_registration_id = push_registration_id_and_sender_id[0]; | 342 const auto& push_subscription_id = push_registration_id_and_sender_id[0]; |
320 const auto& stored_sender_id = push_registration_id_and_sender_id[1]; | 343 const auto& stored_sender_id = push_registration_id_and_sender_id[1]; |
321 std::string fixed_sender_id = | 344 std::string fixed_sender_id = |
322 FixSenderInfo(data.options.sender_info, stored_sender_id); | 345 FixSenderInfo(data.options.sender_info, stored_sender_id); |
323 if (fixed_sender_id.empty()) { | 346 if (fixed_sender_id.empty()) { |
324 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); | 347 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); |
325 return; | 348 return; |
326 } | 349 } |
327 if (fixed_sender_id != stored_sender_id) { | 350 if (fixed_sender_id != stored_sender_id) { |
328 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_SENDER_ID_MISMATCH); | 351 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_SENDER_ID_MISMATCH); |
329 return; | 352 return; |
330 } | 353 } |
331 auto callback = base::Bind( | |
332 &PushMessagingMessageFilter::DidGetEncryptionKeys, | |
333 weak_factory_io_to_io_.GetWeakPtr(), data, push_registration_id); | |
334 BrowserThread::PostTask( | 354 BrowserThread::PostTask( |
335 BrowserThread::UI, FROM_HERE, | 355 BrowserThread::UI, FROM_HERE, |
336 base::Bind(&Core::GetEncryptionInfoOnUI, | 356 base::Bind(&Core::GetSubscriptionInfoOnUI, |
337 base::Unretained(ui_core_.get()), data.requesting_origin, | 357 base::Unretained(ui_core_.get()), data.requesting_origin, |
338 data.service_worker_registration_id, fixed_sender_id, | 358 data.service_worker_registration_id, fixed_sender_id, |
339 callback)); | 359 push_subscription_id, |
360 base::Bind(&Core::SubscribeDidGetInfoOnUI, ui_core_weak_ptr_, | |
361 data, push_subscription_id, fixed_sender_id))); | |
340 return; | 362 return; |
341 } | 363 } |
342 // TODO(johnme): The spec allows the register algorithm to reject with an | 364 // TODO(johnme): The spec allows the register algorithm to reject with an |
343 // AbortError when accessing storage fails. Perhaps we should do that if | 365 // AbortError when accessing storage fails. Perhaps we should do that if |
344 // service_worker_status != SERVICE_WORKER_ERROR_NOT_FOUND instead of | 366 // service_worker_status != SERVICE_WORKER_ERROR_NOT_FOUND instead of |
345 // attempting to do a fresh registration? | 367 // attempting to do a fresh registration? |
346 // https://w3c.github.io/push-api/#widl-PushRegistrationManager-register-Promi se-PushRegistration | 368 // https://w3c.github.io/push-api/#widl-PushRegistrationManager-register-Promi se-PushRegistration |
347 if (!data.options.sender_info.empty()) { | 369 if (!data.options.sender_info.empty()) { |
348 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 370 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
349 base::Bind(&Core::RegisterOnUI, | 371 base::Bind(&Core::RegisterOnUI, |
350 base::Unretained(ui_core_.get()), data)); | 372 base::Unretained(ui_core_.get()), data)); |
351 } else { | 373 } else { |
352 // There is no existing registration and the sender_info passed in was | 374 // There is no existing registration and the sender_info passed in was |
353 // empty, but perhaps there is a stored sender id we can use. | 375 // empty, but perhaps there is a stored sender id we can use. |
354 service_worker_context_->GetRegistrationUserData( | 376 service_worker_context_->GetRegistrationUserData( |
355 data.service_worker_registration_id, {kPushSenderIdServiceWorkerKey}, | 377 data.service_worker_registration_id, {kPushSenderIdServiceWorkerKey}, |
356 base::Bind(&PushMessagingMessageFilter::DidGetSenderIdFromStorage, | 378 base::Bind(&PushMessagingMessageFilter::DidGetSenderIdFromStorage, |
357 weak_factory_io_to_io_.GetWeakPtr(), data)); | 379 weak_factory_io_to_io_.GetWeakPtr(), data)); |
358 } | 380 } |
359 } | 381 } |
360 | 382 |
361 void PushMessagingMessageFilter::DidGetEncryptionKeys( | 383 void PushMessagingMessageFilter::Core::SubscribeDidGetInfoOnUI( |
362 const RegisterData& data, | 384 const RegisterData& data, |
363 const std::string& push_registration_id, | 385 const std::string& push_subscription_id, |
364 bool success, | 386 const std::string& sender_id, |
387 bool is_valid, | |
365 const std::vector<uint8_t>& p256dh, | 388 const std::vector<uint8_t>& p256dh, |
366 const std::vector<uint8_t>& auth) { | 389 const std::vector<uint8_t>& auth) { |
367 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 390 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
368 if (!success) { | 391 if (is_valid) { |
369 SendSubscriptionError( | 392 BrowserThread::PostTask( |
370 data, PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); | 393 BrowserThread::IO, FROM_HERE, |
371 return; | 394 base::Bind(&PushMessagingMessageFilter::SendSubscriptionSuccess, |
395 io_parent_, data, | |
396 PUSH_REGISTRATION_STATUS_SUCCESS_FROM_CACHE, | |
397 push_subscription_id, p256dh, auth)); | |
398 } else { | |
399 // Uh-oh! Although there was a cached subscription in the Service Worker | |
400 // database, it did not have matching counterparts in the | |
401 // PushMessagingAppIdentifier map and/or GCM Store. Unsubscribe and | |
402 // re-subscribe to fix this inconsistency. | |
403 | |
404 // Consider this subscription attempt to have failed. The re-subscribe will | |
405 // be logged to UMA as a separate subscription attempt. | |
406 RecordRegistrationStatus(PUSH_REGISTRATION_STATUS_STORAGE_CORRUPT); | |
407 | |
408 PushMessagingService* push_service = service(); | |
409 DCHECK(push_service); // NOT_FOUND response can only come from service. | |
Peter Beverloo
2017/03/20 23:50:13
Core::GetSubscriptionInfoOnUI specifically returns
johnme
2017/03/30 18:36:38
Hmm yeah. In practice it shouldn't be possible to
| |
410 push_service->Unsubscribe( | |
411 PUSH_UNREGISTRATION_REASON_SUBSCRIBE_STORAGE_CORRUPT, | |
412 data.requesting_origin, data.service_worker_registration_id, sender_id, | |
413 base::Bind(&UnregisterCallbackToClosure, | |
414 base::Bind(IgnoreResult(&BrowserThread::PostTask), | |
415 BrowserThread::IO, FROM_HERE, | |
416 base::Bind(&PushMessagingMessageFilter:: | |
417 DidCheckForExistingRegistration, | |
418 io_parent_, data, | |
419 // push_registration_id_and_sender_id | |
420 std::vector<std::string>(), | |
421 SERVICE_WORKER_ERROR_NOT_FOUND)))); | |
Peter Beverloo
2017/03/20 23:50:13
This is deep. Like, literally. Can we maybe make i
johnme
2017/03/30 18:36:38
Done.
| |
372 } | 422 } |
373 | |
374 SendSubscriptionSuccess(data, PUSH_REGISTRATION_STATUS_SUCCESS_FROM_CACHE, | |
375 push_registration_id, p256dh, auth); | |
376 } | 423 } |
377 | 424 |
378 void PushMessagingMessageFilter::DidGetSenderIdFromStorage( | 425 void PushMessagingMessageFilter::DidGetSenderIdFromStorage( |
379 const RegisterData& data, | 426 const RegisterData& data, |
380 const std::vector<std::string>& stored_sender_id, | 427 const std::vector<std::string>& stored_sender_id, |
381 ServiceWorkerStatusCode service_worker_status) { | 428 ServiceWorkerStatusCode service_worker_status) { |
382 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 429 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
383 if (service_worker_status != SERVICE_WORKER_OK) { | 430 if (service_worker_status != SERVICE_WORKER_OK) { |
384 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); | 431 SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); |
385 return; | 432 return; |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
628 DCHECK(!is_incognito()); | 675 DCHECK(!is_incognito()); |
629 BrowserThread::PostTask( | 676 BrowserThread::PostTask( |
630 BrowserThread::IO, FROM_HERE, | 677 BrowserThread::IO, FROM_HERE, |
631 base::Bind(&PushMessagingMessageFilter::DidUnregister, io_parent_, | 678 base::Bind(&PushMessagingMessageFilter::DidUnregister, io_parent_, |
632 request_id, | 679 request_id, |
633 PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE)); | 680 PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE)); |
634 return; | 681 return; |
635 } | 682 } |
636 | 683 |
637 push_service->Unsubscribe( | 684 push_service->Unsubscribe( |
638 requesting_origin, service_worker_registration_id, sender_id, | 685 PUSH_UNREGISTRATION_REASON_JAVASCRIPT_API, requesting_origin, |
686 service_worker_registration_id, sender_id, | |
639 base::Bind(&Core::DidUnregisterFromService, | 687 base::Bind(&Core::DidUnregisterFromService, |
640 weak_factory_ui_to_ui_.GetWeakPtr(), request_id, | 688 weak_factory_ui_to_ui_.GetWeakPtr(), request_id, |
641 service_worker_registration_id)); | 689 service_worker_registration_id)); |
642 } | 690 } |
643 | 691 |
644 void PushMessagingMessageFilter::Core::DidUnregisterFromService( | 692 void PushMessagingMessageFilter::Core::DidUnregisterFromService( |
645 int request_id, | 693 int request_id, |
646 int64_t service_worker_registration_id, | 694 int64_t service_worker_registration_id, |
647 PushUnregistrationStatus unregistration_status) { | 695 PushUnregistrationStatus unregistration_status) { |
648 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 696 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 int request_id, | 750 int request_id, |
703 int64_t service_worker_registration_id, | 751 int64_t service_worker_registration_id, |
704 const std::vector<std::string>& push_subscription_id_and_sender_info, | 752 const std::vector<std::string>& push_subscription_id_and_sender_info, |
705 ServiceWorkerStatusCode service_worker_status) { | 753 ServiceWorkerStatusCode service_worker_status) { |
706 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 754 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
707 PushGetRegistrationStatus get_status = | 755 PushGetRegistrationStatus get_status = |
708 PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; | 756 PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; |
709 switch (service_worker_status) { | 757 switch (service_worker_status) { |
710 case SERVICE_WORKER_OK: { | 758 case SERVICE_WORKER_OK: { |
711 DCHECK_EQ(2u, push_subscription_id_and_sender_info.size()); | 759 DCHECK_EQ(2u, push_subscription_id_and_sender_info.size()); |
760 const std::string& push_subscription_id = | |
761 push_subscription_id_and_sender_info[0]; | |
762 const std::string& sender_info = push_subscription_id_and_sender_info[1]; | |
712 | 763 |
713 if (!service_available_) { | 764 if (!service_available_) { |
714 // Return not found in incognito mode, so websites can't detect it. | 765 // Return not found in incognito mode, so websites can't detect it. |
715 get_status = | 766 get_status = |
716 ui_core_->is_incognito() | 767 ui_core_->is_incognito() |
717 ? PUSH_GETREGISTRATION_STATUS_INCOGNITO_REGISTRATION_NOT_FOUND | 768 ? PUSH_GETREGISTRATION_STATUS_INCOGNITO_REGISTRATION_NOT_FOUND |
718 : PUSH_GETREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE; | 769 : PUSH_GETREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE; |
719 break; | 770 break; |
720 } | 771 } |
721 | 772 |
722 ServiceWorkerRegistration* registration = | 773 ServiceWorkerRegistration* registration = |
723 service_worker_context_->GetLiveRegistration( | 774 service_worker_context_->GetLiveRegistration( |
724 service_worker_registration_id); | 775 service_worker_registration_id); |
725 const GURL origin = registration->pattern().GetOrigin(); | 776 const GURL origin = registration->pattern().GetOrigin(); |
726 | 777 |
727 const bool uses_standard_protocol = | 778 const bool uses_standard_protocol = IsApplicationServerKey(sender_info); |
728 IsApplicationServerKey(push_subscription_id_and_sender_info[1]); | 779 const GURL endpoint = |
729 const GURL endpoint = CreateEndpoint( | 780 CreateEndpoint(uses_standard_protocol, push_subscription_id); |
730 uses_standard_protocol, push_subscription_id_and_sender_info[0]); | |
731 | |
732 auto callback = | |
733 base::Bind(&PushMessagingMessageFilter::DidGetSubscriptionKeys, | |
734 weak_factory_io_to_io_.GetWeakPtr(), request_id, endpoint, | |
735 push_subscription_id_and_sender_info[1]); | |
736 | 781 |
737 BrowserThread::PostTask( | 782 BrowserThread::PostTask( |
738 BrowserThread::UI, FROM_HERE, | 783 BrowserThread::UI, FROM_HERE, |
739 base::Bind(&Core::GetEncryptionInfoOnUI, | 784 base::Bind(&Core::GetSubscriptionInfoOnUI, |
740 base::Unretained(ui_core_.get()), origin, | 785 base::Unretained(ui_core_.get()), origin, |
741 service_worker_registration_id, | 786 service_worker_registration_id, sender_info, |
742 push_subscription_id_and_sender_info[1], callback)); | 787 push_subscription_id, |
788 base::Bind(&Core::GetSubscriptionDidGetInfoOnUI, | |
789 ui_core_weak_ptr_, request_id, origin, | |
790 service_worker_registration_id, endpoint, | |
791 sender_info))); | |
743 | 792 |
744 return; | 793 return; |
745 } | 794 } |
746 case SERVICE_WORKER_ERROR_NOT_FOUND: { | 795 case SERVICE_WORKER_ERROR_NOT_FOUND: { |
747 get_status = PUSH_GETREGISTRATION_STATUS_REGISTRATION_NOT_FOUND; | 796 get_status = PUSH_GETREGISTRATION_STATUS_REGISTRATION_NOT_FOUND; |
748 break; | 797 break; |
749 } | 798 } |
750 case SERVICE_WORKER_ERROR_FAILED: { | 799 case SERVICE_WORKER_ERROR_FAILED: { |
751 get_status = PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; | 800 get_status = PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; |
752 break; | 801 break; |
(...skipping 18 matching lines...) Expand all Loading... | |
771 NOTREACHED() << "Got unexpected error code: " << service_worker_status | 820 NOTREACHED() << "Got unexpected error code: " << service_worker_status |
772 << " " << ServiceWorkerStatusToString(service_worker_status); | 821 << " " << ServiceWorkerStatusToString(service_worker_status); |
773 get_status = PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; | 822 get_status = PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR; |
774 break; | 823 break; |
775 } | 824 } |
776 } | 825 } |
777 Send(new PushMessagingMsg_GetSubscriptionError(request_id, get_status)); | 826 Send(new PushMessagingMsg_GetSubscriptionError(request_id, get_status)); |
778 RecordGetRegistrationStatus(get_status); | 827 RecordGetRegistrationStatus(get_status); |
779 } | 828 } |
780 | 829 |
781 void PushMessagingMessageFilter::DidGetSubscriptionKeys( | 830 void PushMessagingMessageFilter::Core::GetSubscriptionDidGetInfoOnUI( |
782 int request_id, | 831 int request_id, |
832 const GURL& origin, | |
833 int64_t service_worker_registration_id, | |
783 const GURL& endpoint, | 834 const GURL& endpoint, |
784 const std::string& sender_info, | 835 const std::string& sender_info, |
785 bool success, | 836 bool is_valid, |
786 const std::vector<uint8_t>& p256dh, | 837 const std::vector<uint8_t>& p256dh, |
787 const std::vector<uint8_t>& auth) { | 838 const std::vector<uint8_t>& auth) { |
788 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 839 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
789 if (!success) { | 840 if (is_valid) { |
841 PushSubscriptionOptions options; | |
842 // Chrome rejects subscription requests with userVisibleOnly false, so it | |
843 // must have been true. TODO(harkness): If Chrome starts accepting silent | |
844 // push subscriptions with userVisibleOnly false, the bool will need to be | |
845 // stored. | |
846 options.user_visible_only = true; | |
847 options.sender_info = sender_info; | |
848 | |
849 Send(new PushMessagingMsg_GetSubscriptionSuccess(request_id, endpoint, | |
850 options, p256dh, auth)); | |
851 | |
852 RecordGetRegistrationStatus(PUSH_GETREGISTRATION_STATUS_SUCCESS); | |
853 } else { | |
854 // Uh-oh! Although there was a cached subscription in the Service Worker | |
855 // database, it did not have matching counterparts in the | |
856 // PushMessagingAppIdentifier map and/or GCM Store. Unsubscribe to fix this | |
857 // inconsistency. | |
790 PushGetRegistrationStatus status = | 858 PushGetRegistrationStatus status = |
791 PUSH_GETREGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE; | 859 PUSH_GETREGISTRATION_STATUS_STORAGE_CORRUPT; |
792 | 860 |
793 Send(new PushMessagingMsg_GetSubscriptionError(request_id, status)); | 861 PushMessagingService* push_service = service(); |
862 DCHECK(push_service); // NOT_FOUND response can only come from service. | |
863 push_service->Unsubscribe( | |
864 PUSH_UNREGISTRATION_REASON_GET_SUBSCRIPTION_STORAGE_CORRUPT, origin, | |
865 service_worker_registration_id, sender_info, | |
866 base::Bind(&Core::GetSubscriptionDidUnsubscribe, | |
867 weak_factory_ui_to_ui_.GetWeakPtr(), request_id, status)); | |
794 | 868 |
795 RecordGetRegistrationStatus(status); | 869 RecordGetRegistrationStatus(status); |
796 return; | |
797 } | 870 } |
871 } | |
798 | 872 |
799 PushSubscriptionOptions options; | 873 void PushMessagingMessageFilter::Core::GetSubscriptionDidUnsubscribe( |
800 // Chrome rejects subscription requests with userVisibleOnly false, so it must | 874 int request_id, |
801 // have been true. TODO(harkness): If Chrome starts accepting silent push | 875 PushGetRegistrationStatus get_status, |
802 // subscriptions with userVisibleOnly false, the bool will need to be stored. | 876 PushUnregistrationStatus unsubscribe_status) { |
803 options.user_visible_only = true; | 877 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
804 options.sender_info = sender_info; | 878 Send(new PushMessagingMsg_GetSubscriptionError(request_id, get_status)); |
805 | |
806 Send(new PushMessagingMsg_GetSubscriptionSuccess(request_id, endpoint, | |
807 options, p256dh, auth)); | |
808 | |
809 RecordGetRegistrationStatus(PUSH_GETREGISTRATION_STATUS_SUCCESS); | |
810 } | 879 } |
811 | 880 |
812 // GetPermission methods on both IO and UI threads, merged in order of use from | 881 // GetPermission methods on both IO and UI threads, merged in order of use from |
813 // PushMessagingMessageFilter and Core. | 882 // PushMessagingMessageFilter and Core. |
814 // ----------------------------------------------------------------------------- | 883 // ----------------------------------------------------------------------------- |
815 | 884 |
816 void PushMessagingMessageFilter::OnGetPermissionStatus( | 885 void PushMessagingMessageFilter::OnGetPermissionStatus( |
817 int request_id, | 886 int request_id, |
818 int64_t service_worker_registration_id, | 887 int64_t service_worker_registration_id, |
819 bool user_visible) { | 888 bool user_visible) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
857 return; | 926 return; |
858 } | 927 } |
859 Send(new PushMessagingMsg_GetPermissionStatusSuccess(request_id, | 928 Send(new PushMessagingMsg_GetPermissionStatusSuccess(request_id, |
860 permission_status)); | 929 permission_status)); |
861 } | 930 } |
862 | 931 |
863 // Helper methods on both IO and UI threads, merged from | 932 // Helper methods on both IO and UI threads, merged from |
864 // PushMessagingMessageFilter and Core. | 933 // PushMessagingMessageFilter and Core. |
865 // ----------------------------------------------------------------------------- | 934 // ----------------------------------------------------------------------------- |
866 | 935 |
867 void PushMessagingMessageFilter::Core::GetEncryptionInfoOnUI( | 936 void PushMessagingMessageFilter::Core::GetSubscriptionInfoOnUI( |
868 const GURL& origin, | 937 const GURL& origin, |
869 int64_t service_worker_registration_id, | 938 int64_t service_worker_registration_id, |
870 const std::string& sender_id, | 939 const std::string& sender_id, |
871 const PushMessagingService::EncryptionInfoCallback& io_thread_callback) { | 940 const std::string& push_subscription_id, |
941 const PushMessagingService::SubscriptionInfoCallback& callback) { | |
872 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 942 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
873 PushMessagingService* push_service = service(); | 943 PushMessagingService* push_service = service(); |
874 if (push_service) { | 944 if (!push_service) { |
875 push_service->GetEncryptionInfo( | 945 callback.Run(false /* is_valid */, std::vector<uint8_t>() /* p256dh */, |
876 origin, service_worker_registration_id, sender_id, | 946 std::vector<uint8_t>() /* auth */); |
877 base::Bind(&ForwardEncryptionInfoToIOThreadProxy, io_thread_callback)); | |
878 return; | 947 return; |
879 } | 948 } |
880 | 949 |
881 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 950 push_service->GetSubscriptionInfo(origin, service_worker_registration_id, |
882 base::Bind(io_thread_callback, false /* success */, | 951 sender_id, push_subscription_id, callback); |
883 std::vector<uint8_t>() /* p256dh */, | |
884 std::vector<uint8_t>() /* auth */)); | |
885 } | 952 } |
886 | 953 |
887 void PushMessagingMessageFilter::Core::Send(IPC::Message* message) { | 954 void PushMessagingMessageFilter::Core::Send(IPC::Message* message) { |
888 BrowserThread::PostTask( | 955 BrowserThread::PostTask( |
889 BrowserThread::IO, FROM_HERE, | 956 BrowserThread::IO, FROM_HERE, |
890 base::Bind(&PushMessagingMessageFilter::SendIPC, io_parent_, | 957 base::Bind(&PushMessagingMessageFilter::SendIPC, io_parent_, |
891 base::Passed(base::WrapUnique(message)))); | 958 base::Passed(base::WrapUnique(message)))); |
892 } | 959 } |
893 | 960 |
894 void PushMessagingMessageFilter::SendIPC( | 961 void PushMessagingMessageFilter::SendIPC( |
(...skipping 12 matching lines...) Expand all Loading... | |
907 | 974 |
908 PushMessagingService* PushMessagingMessageFilter::Core::service() { | 975 PushMessagingService* PushMessagingMessageFilter::Core::service() { |
909 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 976 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
910 RenderProcessHost* process_host = | 977 RenderProcessHost* process_host = |
911 RenderProcessHost::FromID(render_process_id_); | 978 RenderProcessHost::FromID(render_process_id_); |
912 return process_host | 979 return process_host |
913 ? process_host->GetBrowserContext()->GetPushMessagingService() | 980 ? process_host->GetBrowserContext()->GetPushMessagingService() |
914 : nullptr; | 981 : nullptr; |
915 } | 982 } |
916 | 983 |
984 base::WeakPtr<PushMessagingMessageFilter::Core> | |
985 PushMessagingMessageFilter::Core::GetWeakPtrFromIOParentConstructor() { | |
Peter Beverloo
2017/03/20 23:50:13
Would you mind summarising in two sentences or so
johnme
2017/03/30 18:36:38
weak_factory_ui_to_ui_ should not be public, as it
| |
986 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
987 return weak_factory_ui_to_ui_.GetWeakPtr(); | |
988 } | |
989 | |
917 } // namespace content | 990 } // namespace content |
OLD | NEW |