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"
9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h"
11 #include "components/gcm_driver/gcm_app_handler.h"
16 const char kGCMFieldTrialName
[] = "GCM";
17 const char kGCMFieldTrialEnabledGroupName
[] = "Enabled";
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
);
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
);
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
) {
72 // If previous un/register operation is still in progress, bail out.
73 if (IsAsyncOperationPending(app_id
)) {
74 callback
.Run(GCMClient::ASYNC_OPERATION_PENDING
);
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
);
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
);
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.
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())
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.
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());
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())
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
))
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();