Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / gcm_driver / gcm_driver.cc
blobe9ff81975aac5f9d4b4bd064bcf67c4216761314
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.
5 #include "components/gcm_driver/gcm_driver.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h"
11 #include "components/gcm_driver/gcm_app_handler.h"
13 namespace gcm {
15 namespace {
16 const char kGCMFieldTrialName[] = "GCM";
17 const char kGCMFieldTrialEnabledGroupName[] = "Enabled";
18 } // namespace
20 // static
21 bool GCMDriver::IsAllowedForAllUsers() {
22 std::string group_name =
23 base::FieldTrialList::FindFullName(kGCMFieldTrialName);
24 return group_name == kGCMFieldTrialEnabledGroupName;
27 GCMDriver::GCMDriver() {
30 GCMDriver::~GCMDriver() {
33 void GCMDriver::Register(const std::string& app_id,
34 const std::vector<std::string>& sender_ids,
35 const RegisterCallback& callback) {
36 DCHECK(!app_id.empty());
37 DCHECK(!sender_ids.empty());
38 DCHECK(!callback.is_null());
40 GCMClient::Result result = EnsureStarted();
41 if (result != GCMClient::SUCCESS) {
42 callback.Run(std::string(), result);
43 return;
46 // If previous un/register operation is still in progress, bail out.
47 if (IsAsyncOperationPending(app_id)) {
48 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
49 return;
52 // Normalize the sender IDs by making them sorted.
53 std::vector<std::string> normalized_sender_ids = sender_ids;
54 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
56 register_callbacks_[app_id] = callback;
58 RegisterImpl(app_id, normalized_sender_ids);
61 void GCMDriver::Unregister(const std::string& app_id,
62 const UnregisterCallback& callback) {
63 DCHECK(!app_id.empty());
64 DCHECK(!callback.is_null());
66 GCMClient::Result result = EnsureStarted();
67 if (result != GCMClient::SUCCESS) {
68 callback.Run(result);
69 return;
72 // If previous un/register operation is still in progress, bail out.
73 if (IsAsyncOperationPending(app_id)) {
74 callback.Run(GCMClient::ASYNC_OPERATION_PENDING);
75 return;
78 unregister_callbacks_[app_id] = callback;
80 UnregisterImpl(app_id);
83 void GCMDriver::Send(const std::string& app_id,
84 const std::string& receiver_id,
85 const GCMClient::OutgoingMessage& message,
86 const SendCallback& callback) {
87 DCHECK(!app_id.empty());
88 DCHECK(!receiver_id.empty());
89 DCHECK(!callback.is_null());
91 GCMClient::Result result = EnsureStarted();
92 if (result != GCMClient::SUCCESS) {
93 callback.Run(std::string(), result);
94 return;
97 // If the message with send ID is still in progress, bail out.
98 std::pair<std::string, std::string> key(app_id, message.id);
99 if (send_callbacks_.find(key) != send_callbacks_.end()) {
100 callback.Run(message.id, GCMClient::INVALID_PARAMETER);
101 return;
104 send_callbacks_[key] = callback;
106 SendImpl(app_id, receiver_id, message);
109 void GCMDriver::RegisterFinished(const std::string& app_id,
110 const std::string& registration_id,
111 GCMClient::Result result) {
112 std::map<std::string, RegisterCallback>::iterator callback_iter =
113 register_callbacks_.find(app_id);
114 if (callback_iter == register_callbacks_.end()) {
115 // The callback could have been removed when the app is uninstalled.
116 return;
119 RegisterCallback callback = callback_iter->second;
120 register_callbacks_.erase(callback_iter);
121 callback.Run(registration_id, result);
124 void GCMDriver::UnregisterFinished(const std::string& app_id,
125 GCMClient::Result result) {
126 std::map<std::string, UnregisterCallback>::iterator callback_iter =
127 unregister_callbacks_.find(app_id);
128 if (callback_iter == unregister_callbacks_.end())
129 return;
131 UnregisterCallback callback = callback_iter->second;
132 unregister_callbacks_.erase(callback_iter);
133 callback.Run(result);
136 void GCMDriver::SendFinished(const std::string& app_id,
137 const std::string& message_id,
138 GCMClient::Result result) {
139 std::map<std::pair<std::string, std::string>, SendCallback>::iterator
140 callback_iter = send_callbacks_.find(
141 std::pair<std::string, std::string>(app_id, message_id));
142 if (callback_iter == send_callbacks_.end()) {
143 // The callback could have been removed when the app is uninstalled.
144 return;
147 SendCallback callback = callback_iter->second;
148 send_callbacks_.erase(callback_iter);
149 callback.Run(message_id, result);
152 void GCMDriver::Shutdown() {
153 for (GCMAppHandlerMap::const_iterator iter = app_handlers_.begin();
154 iter != app_handlers_.end(); ++iter) {
155 iter->second->ShutdownHandler();
157 app_handlers_.clear();
160 void GCMDriver::AddAppHandler(const std::string& app_id,
161 GCMAppHandler* handler) {
162 DCHECK(!app_id.empty());
163 DCHECK(handler);
164 DCHECK_EQ(app_handlers_.count(app_id), 0u);
165 app_handlers_[app_id] = handler;
168 void GCMDriver::RemoveAppHandler(const std::string& app_id) {
169 DCHECK(!app_id.empty());
170 app_handlers_.erase(app_id);
173 GCMAppHandler* GCMDriver::GetAppHandler(const std::string& app_id) {
174 // Look for exact match.
175 GCMAppHandlerMap::const_iterator iter = app_handlers_.find(app_id);
176 if (iter != app_handlers_.end())
177 return iter->second;
179 // Ask the handlers whether they know how to handle it.
180 for (iter = app_handlers_.begin(); iter != app_handlers_.end(); ++iter) {
181 if (iter->second->CanHandle(app_id))
182 return iter->second;
185 return &default_app_handler_;
188 bool GCMDriver::HasRegisterCallback(const std::string& app_id) {
189 return register_callbacks_.find(app_id) != register_callbacks_.end();
192 void GCMDriver::ClearCallbacks() {
193 register_callbacks_.clear();
194 unregister_callbacks_.clear();
195 send_callbacks_.clear();
198 bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const {
199 return register_callbacks_.find(app_id) != register_callbacks_.end() ||
200 unregister_callbacks_.find(app_id) != unregister_callbacks_.end();
203 } // namespace gcm