| 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 "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_permission_context.h" | 17 #include "chrome/browser/services/gcm/push_messaging_permission_context.h" |
| 18 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory.
h" | 18 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory.
h" |
| 19 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
| 21 #include "components/gcm_driver/gcm_driver.h" | 21 #include "components/gcm_driver/gcm_driver.h" |
| 22 #include "components/pref_registry/pref_registry_syncable.h" | 22 #include "components/pref_registry/pref_registry_syncable.h" |
| 23 #include "content/public/browser/push_messaging_application_id.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 Loading... |
| 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( |
| 67 content::kPushMessagingApplicationIdPrefix, 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 content::PushMessagingApplicationId::Parse(app_id).is_valid(); |
| 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 content::PushMessagingApplicationId application_id = |
| 108 content::PushMessagingApplicationId::Parse(app_id); |
| 109 DCHECK(application_id.is_valid()); |
| 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.is_valid() && 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 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 145 RegisterEnd( | 148 RegisterEnd( |
| 146 app_id, | 149 app_id, |
| 147 callback, | 150 callback, |
| 148 std::string(), | 151 std::string(), |
| 149 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_LIMIT_REACHED); | 152 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_LIMIT_REACHED); |
| 150 return; | 153 return; |
| 151 } | 154 } |
| 152 | 155 |
| 153 // If this is registering for the first time then the driver does not have | 156 // If this is registering for the first time then the driver does not have |
| 154 // this as an app handler and registration would fail. | 157 // this as an app handler and registration would fail. |
| 155 if (gcm_profile_service_->driver()->GetAppHandler(kAppIdPrefix) != this) | 158 if (gcm_profile_service_->driver()->GetAppHandler( |
| 156 gcm_profile_service_->driver()->AddAppHandler(kAppIdPrefix, this); | 159 content::kPushMessagingApplicationIdPrefix) != this) |
| 160 gcm_profile_service_->driver()->AddAppHandler( |
| 161 content::kPushMessagingApplicationIdPrefix, this); |
| 157 | 162 |
| 158 content::RenderFrameHost* render_frame_host = | 163 content::RenderFrameHost* render_frame_host = |
| 159 content::RenderFrameHost::FromID(renderer_id, render_frame_id); | 164 content::RenderFrameHost::FromID(renderer_id, render_frame_id); |
| 160 | 165 |
| 161 // The frame doesn't exist any more, or we received a bad frame id. | 166 // The frame doesn't exist any more, or we received a bad frame id. |
| 162 if (!render_frame_host) | 167 if (!render_frame_host) |
| 163 return; | 168 return; |
| 164 | 169 |
| 165 content::WebContents* web_contents = | 170 content::WebContents* web_contents = |
| 166 content::WebContents::FromRenderFrameHost(render_frame_host); | 171 content::WebContents::FromRenderFrameHost(render_frame_host); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 base::Bind(&PushMessagingServiceImpl::DidRegister, | 260 base::Bind(&PushMessagingServiceImpl::DidRegister, |
| 256 weak_factory_.GetWeakPtr(), | 261 weak_factory_.GetWeakPtr(), |
| 257 app_id, | 262 app_id, |
| 258 register_callback)); | 263 register_callback)); |
| 259 } | 264 } |
| 260 | 265 |
| 261 // TODO(johnme): Unregister should decrement the pref, and call | 266 // TODO(johnme): Unregister should decrement the pref, and call |
| 262 // RemoveAppHandler if the count drops to zero. | 267 // RemoveAppHandler if the count drops to zero. |
| 263 | 268 |
| 264 } // namespace gcm | 269 } // namespace gcm |
| OLD | NEW |