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

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

Issue 340773006: Dispatch push event to worker from PushServiceImpl#OnMessage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Debugging. Created 6 years, 6 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
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"
13 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/services/gcm/gcm_profile_service.h" 13 #include "chrome/browser/services/gcm/gcm_profile_service.h"
15 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 14 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
16 #include "chrome/common/chrome_switches.h" 15 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
18 #include "components/gcm_driver/gcm_driver.h" 17 #include "components/gcm_driver/gcm_driver.h"
19 #include "components/pref_registry/pref_registry_syncable.h" 18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "content/browser/service_worker/service_worker_context_wrapper.h"
20 #include "content/browser/service_worker/service_worker_registration.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/push_messaging_application_id.h"
23 #include "content/public/browser/storage_partition.h"
24
25 using content::BrowserContext;
26 using content::BrowserThread;
27 using content::PushMessagingApplicationId;
28 using content::ServiceWorkerContextWrapper;
20 29
21 namespace gcm { 30 namespace gcm {
22 31
23 namespace { 32 namespace {
24 const char kAppIdPrefix[] = "push:"; 33 // TODO(mvanouwerkerk): Move this to a public shared place.
34 const char kAppIdPrefix[] = "push";
25 const int kMaxRegistrations = 1000000; 35 const int kMaxRegistrations = 1000000;
26 } // namespace 36 } // namespace
27 37
28 // static 38 // static
29 void PushMessagingServiceImpl::RegisterProfilePrefs( 39 void PushMessagingServiceImpl::RegisterProfilePrefs(
30 user_prefs::PrefRegistrySyncable* registry) { 40 user_prefs::PrefRegistrySyncable* registry) {
31 registry->RegisterIntegerPref( 41 registry->RegisterIntegerPref(
32 prefs::kPushMessagingRegistrationCount, 42 prefs::kPushMessagingRegistrationCount,
33 0, 43 0,
34 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 44 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 profile_(profile), 78 profile_(profile),
69 weak_factory_(this) { 79 weak_factory_(this) {
70 } 80 }
71 81
72 PushMessagingServiceImpl::~PushMessagingServiceImpl() { 82 PushMessagingServiceImpl::~PushMessagingServiceImpl() {
73 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver, 83 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver,
74 // then we should call RemoveAppHandler. 84 // then we should call RemoveAppHandler.
75 } 85 }
76 86
77 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const { 87 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const {
78 // TODO(mvanouwerkerk): Finalize and centralize format of Push API app_id. 88 return PushMessagingApplicationId::IsValid(app_id);
79 return StartsWithASCII(app_id, kAppIdPrefix, true);
80 } 89 }
81 90
82 void PushMessagingServiceImpl::ShutdownHandler() { 91 void PushMessagingServiceImpl::ShutdownHandler() {
83 // TODO(johnme): Do any necessary cleanup. 92 // TODO(johnme): Do any necessary cleanup.
84 } 93 }
85 94
86 void PushMessagingServiceImpl::OnMessage( 95 void PushMessagingServiceImpl::OnMessage(
87 const std::string& app_id, 96 const std::string& app_id,
88 const GCMClient::IncomingMessage& message) { 97 const GCMClient::IncomingMessage& message) {
98 LOG(WARNING) << "app_id: " << app_id;
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89 // The Push API only exposes a single string of data in the push event fired 100 // The Push API only exposes a single string of data in the push event fired
90 // on the Service Worker. When developers send messages using GCM to the Push 101 // on the Service Worker. When developers send messages using GCM to the Push
91 // API, they must pass a single key-value pair, where the key is "data" and 102 // API, they must pass a single key-value pair, where the key is "data" and
92 // the value is the string they want to be passed to their Service Worker. 103 // the value is the string they want to be passed to their Service Worker.
93 // For example, they could send the following JSON using the HTTPS GCM API: 104 // For example, they could send the following JSON using the HTTPS GCM API:
94 // { 105 // {
95 // "registration_ids": ["FOO", "BAR"], 106 // "registration_ids": ["FOO", "BAR"],
96 // "data": { 107 // "data": {
97 // "data": "BAZ", 108 // "data": "BAZ",
98 // }, 109 // },
99 // "delay_while_idle": true, 110 // "delay_while_idle": true,
100 // } 111 // }
101 // TODO(johnme): Make sure this is clearly documented for developers. 112 // TODO(johnme): Make sure this is clearly documented for developers.
113 PushMessagingApplicationId id = PushMessagingApplicationId::Parse(app_id);
114 DCHECK(id.is_valid());
102 GCMClient::MessageData::const_iterator it = message.data.find("data"); 115 GCMClient::MessageData::const_iterator it = message.data.find("data");
103 if (it != message.data.end()) { 116 if (id.is_valid() && it != message.data.end()) {
104 const std::string& data ALLOW_UNUSED = it->second; 117 const std::string& data = it->second;
105 // TODO(mvanouwerkerk): Fire push event with data on the Service Worker 118 content::StoragePartition* partition =
106 // corresponding to app_id (and remove ALLOW_UNUSED above). 119 BrowserContext::GetStoragePartitionForSite(profile_, id.origin);
120 scoped_refptr<ServiceWorkerContextWrapper> worker_context =
121 static_cast<ServiceWorkerContextWrapper*>(
122 partition->GetServiceWorkerContext());
123 BrowserThread::PostTask(BrowserThread::IO,
124 FROM_HERE,
125 base::Bind(&PushMessagingServiceImpl::SendMessage,
126 weak_factory_.GetWeakPtr(),
127 id,
128 data,
129 worker_context));
107 } else { 130 } else {
131 LOG(WARNING) << "Dropping the message.";
108 // Drop the message, as it is invalid. 132 // Drop the message, as it is invalid.
109 // TODO(mvanouwerkerk): Show a warning in the developer console of the 133 // TODO(mvanouwerkerk): Show a warning in the developer console of the
110 // Service Worker corresponding to app_id. 134 // Service Worker corresponding to app_id.
111 // TODO(johnme): Add diagnostic observers (e.g. UMA and an internals page) 135 // TODO(johnme): Add diagnostic observers (e.g. UMA and an internals page)
112 // to know when bad things happen. 136 // to know when bad things happen.
113 } 137 }
114 } 138 }
115 139
140 void PushMessagingServiceImpl::SendMessage(
141 const PushMessagingApplicationId& id,
142 const std::string& data,
143 scoped_refptr<ServiceWorkerContextWrapper> worker_context) {
144 LOG(WARNING) << "data: " << data;
145 // TODO(mvanouwerkerk): Can this method live in content::PushMessagingService?
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
147 content::ServiceWorkerRegistration* worker_registration =
148 worker_context->context()->GetLiveRegistration(id.worker_registration_id);
149 if (worker_registration) {
150 base::Callback<void(ServiceWorkerStatusCode)> callback =
151 base::Bind(&PushMessagingServiceImpl::SendMessageCallback,
152 weak_factory_.GetWeakPtr());
153 worker_registration->active_version()->DispatchPushEvent(callback, data);
154 } else {
155 // TODO(mvanouwerkerk): UMA logging. Can we recover from failure?
156 LOG(WARNING) << "Could not find ServiceWorkerRegistration.";
157 }
158 }
159
160 void PushMessagingServiceImpl::SendMessageCallback(
161 ServiceWorkerStatusCode status) {
162 // TODO(mvanouwerkerk): UMA logging. Can we recover from failures?
163 LOG(WARNING) << "ServiceWorkerStatusCode: " << status;
164 }
165
116 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) { 166 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) {
117 // TODO(mvanouwerkerk): Fire push error event on the Service Worker 167 // TODO(mvanouwerkerk): Fire push error event on the Service Worker
118 // corresponding to app_id. 168 // corresponding to app_id.
119 } 169 }
120 170
121 void PushMessagingServiceImpl::OnSendError( 171 void PushMessagingServiceImpl::OnSendError(
122 const std::string& app_id, 172 const std::string& app_id,
123 const GCMClient::SendErrorDetails& send_error_details) { 173 const GCMClient::SendErrorDetails& send_error_details) {
124 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; 174 NOTREACHED() << "The Push API shouldn't have sent messages upstream";
125 } 175 }
126 176
127 void PushMessagingServiceImpl::Register( 177 void PushMessagingServiceImpl::Register(
128 const std::string& app_id, 178 const std::string& app_id,
129 const std::string& sender_id, 179 const std::string& sender_id,
130 const content::PushMessagingService::RegisterCallback& callback) { 180 const content::PushMessagingService::RegisterCallback& callback) {
181 LOG(WARNING) << "app_id: " << app_id;
131 if (!gcm_profile_service_->driver()) { 182 if (!gcm_profile_service_->driver()) {
132 NOTREACHED() << "There is no GCMDriver. Has GCMProfileService shut down?"; 183 NOTREACHED() << "There is no GCMDriver. Has GCMProfileService shut down?";
133 } 184 }
134 185
135 if (profile_->GetPrefs()->GetInteger( 186 if (profile_->GetPrefs()->GetInteger(
136 prefs::kPushMessagingRegistrationCount) >= kMaxRegistrations) { 187 prefs::kPushMessagingRegistrationCount) >= kMaxRegistrations) {
188 LOG(WARNING) << "Registration limit has been reached.";
137 DidRegister(app_id, callback, "", GCMClient::UNKNOWN_ERROR); 189 DidRegister(app_id, callback, "", GCMClient::UNKNOWN_ERROR);
138 return; 190 return;
139 } 191 }
140 192
141 // If this is registering for the first time then the driver does not have 193 // If this is registering for the first time then the driver does not have
142 // this as an app handler and registration would fail. 194 // this as an app handler and registration would fail.
143 if (gcm_profile_service_->driver()->GetAppHandler(kAppIdPrefix) != this) 195 if (gcm_profile_service_->driver()->GetAppHandler(kAppIdPrefix) != this)
144 gcm_profile_service_->driver()->AddAppHandler(kAppIdPrefix, this); 196 gcm_profile_service_->driver()->AddAppHandler(kAppIdPrefix, this);
145 197
146 std::vector<std::string> sender_ids(1, sender_id); 198 std::vector<std::string> sender_ids(1, sender_id);
147 gcm_profile_service_->driver()->Register( 199 gcm_profile_service_->driver()->Register(
148 app_id, 200 app_id,
149 sender_ids, 201 sender_ids,
150 base::Bind(&PushMessagingServiceImpl::DidRegister, 202 base::Bind(&PushMessagingServiceImpl::DidRegister,
151 weak_factory_.GetWeakPtr(), 203 weak_factory_.GetWeakPtr(),
152 app_id, 204 app_id,
153 callback)); 205 callback));
154 } 206 }
155 207
156 void PushMessagingServiceImpl::DidRegister( 208 void PushMessagingServiceImpl::DidRegister(
157 const std::string& app_id, 209 const std::string& app_id,
158 const content::PushMessagingService::RegisterCallback& callback, 210 const content::PushMessagingService::RegisterCallback& callback,
159 const std::string& registration_id, 211 const std::string& registration_id,
160 GCMClient::Result result) { 212 GCMClient::Result result) {
213 LOG(WARNING) << "result: " << result;
161 GURL endpoint = GURL("https://android.googleapis.com/gcm/send"); 214 GURL endpoint = GURL("https://android.googleapis.com/gcm/send");
162 bool success = (result == GCMClient::SUCCESS); 215 bool success = (result == GCMClient::SUCCESS);
163 callback.Run(endpoint, registration_id, success); 216 callback.Run(endpoint, registration_id, success);
164 if (success) { 217 if (success) {
165 // TODO(johnme): Make sure the pref doesn't get out of sync after crashes. 218 // TODO(johnme): Make sure the pref doesn't get out of sync after crashes.
166 int registration_count = profile_->GetPrefs()->GetInteger( 219 int registration_count = profile_->GetPrefs()->GetInteger(
167 prefs::kPushMessagingRegistrationCount); 220 prefs::kPushMessagingRegistrationCount);
168 profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, 221 profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount,
169 registration_count + 1); 222 registration_count + 1);
170 } 223 }
171 } 224 }
172 225
173 // TODO(johnme): Unregister should decrement the pref, and call 226 // TODO(johnme): Unregister should decrement the pref, and call
174 // RemoveAppHandler if the count drops to zero. 227 // RemoveAppHandler if the count drops to zero.
175 228
176 } // namespace gcm 229 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698