1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
#define CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/services/gcm/default_gcm_app_handler.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "google_apis/gcm/gcm_client.h"
class Profile;
namespace base {
class Value;
}
namespace extensions {
class ExtensionGCMAppHandlerTest;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace gcm {
class GCMAppHandler;
class GCMClientFactory;
class GCMProfileServiceTestConsumer;
// Acts as a bridge between GCM API and GCMClient layer. It is profile based.
class GCMProfileService : public KeyedService,
public content::NotificationObserver,
public SigninManagerBase::Observer {
public:
typedef base::Callback<void(const std::string& registration_id,
GCMClient::Result result)> RegisterCallback;
typedef base::Callback<void(const std::string& message_id,
GCMClient::Result result)> SendCallback;
typedef base::Callback<void(GCMClient::Result result)> UnregisterCallback;
typedef base::Callback<void(const GCMClient::GCMStatistics& stats)>
RequestGCMStatisticsCallback;
// Any change made to this enum should have corresponding change in the
// GetGCMEnabledStateString(...) function.
enum GCMEnabledState {
// GCM is always enabled. GCMClient will always load and connect with GCM.
ALWAYS_ENABLED,
// GCM is only enabled for apps. GCMClient will start to load and connect
// with GCM only when GCM API is used.
ENABLED_FOR_APPS,
// GCM is always disabled. GCMClient will never load and connect with GCM.
ALWAYS_DISABLED
};
// Returns the GCM enabled state.
static GCMEnabledState GetGCMEnabledState(Profile* profile);
// Returns text representation of a GCMEnabledState enum entry.
static std::string GetGCMEnabledStateString(GCMEnabledState state);
// Register profile-specific prefs for GCM.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
explicit GCMProfileService(Profile* profile);
virtual ~GCMProfileService();
void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory);
void Start();
void Stop();
// KeyedService implementation.
virtual void Shutdown() OVERRIDE;
// Adds a handler for a given app.
virtual void AddAppHandler(const std::string& app_id, GCMAppHandler* handler);
// Remove the handler for a given app.
virtual void RemoveAppHandler(const std::string& app_id);
// Registers |sender_id| for an app. A registration ID will be returned by
// the GCM server.
// |app_id|: application ID.
// |sender_ids|: list of IDs of the servers that are allowed to send the
// messages to the application. These IDs are assigned by the
// Google API Console.
// |callback|: to be called once the asynchronous operation is done.
virtual void Register(const std::string& app_id,
const std::vector<std::string>& sender_ids,
RegisterCallback callback);
// Unregisters an app from using GCM.
// |app_id|: application ID.
// |callback|: to be called once the asynchronous operation is done.
virtual void Unregister(const std::string& app_id,
UnregisterCallback callback);
// Sends a message to a given receiver.
// |app_id|: application ID.
// |receiver_id|: registration ID of the receiver party.
// |message|: message to be sent.
// |callback|: to be called once the asynchronous operation is done.
virtual void Send(const std::string& app_id,
const std::string& receiver_id,
const GCMClient::OutgoingMessage& message,
SendCallback callback);
// For testing purpose.
GCMClient* GetGCMClientForTesting() const;
// Returns the user name if the profile is signed in.
std::string SignedInUserName() const;
// Returns true if the gcm client is ready.
bool IsGCMClientReady() const;
// Get GCM client internal states and statistics. If it has not been created
// then stats won't be modified.
void RequestGCMStatistics(RequestGCMStatisticsCallback callback);
private:
friend class GCMProfileServiceTestConsumer;
friend class extensions::ExtensionGCMAppHandlerTest;
class DelayedTaskController;
class IOWorker;
typedef std::map<std::string, GCMAppHandler*> GCMAppHandlerMap;
// Overridden from content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// Overridden from SigninManagerBase::Observer:
virtual void GoogleSigninSucceeded(const std::string& username,
const std::string& password) OVERRIDE;
virtual void GoogleSignedOut(const std::string& username) OVERRIDE;
// Ensures that the GCMClient is loaded and the GCM check-in is done when
// the profile was signed in.
void EnsureLoaded();
// Remove cached data when GCM service is stopped.
void RemoveCachedData();
// Checks out of GCM when the profile has been signed out. This will erase
// all the cached and persisted data.
void CheckOut();
// Resets the GCMClient instance. This is called when the profile is being
// destroyed.
void ResetGCMClient();
// Ensures that the app is ready for GCM functions and events.
GCMClient::Result EnsureAppReady(const std::string& app_id);
// Should be called when an app with |app_id| is trying to un/register.
// Checks whether another un/registration is in progress.
bool IsAsyncOperationPending(const std::string& app_id) const;
void DoRegister(const std::string& app_id,
const std::vector<std::string>& sender_ids);
void DoUnregister(const std::string& app_id);
void DoSend(const std::string& app_id,
const std::string& receiver_id,
const GCMClient::OutgoingMessage& message);
// Callbacks posted from IO thread to UI thread.
void RegisterFinished(const std::string& app_id,
const std::string& registration_id,
GCMClient::Result result);
void UnregisterFinished(const std::string& app_id, GCMClient::Result result);
void SendFinished(const std::string& app_id,
const std::string& message_id,
GCMClient::Result result);
void MessageReceived(const std::string& app_id,
GCMClient::IncomingMessage message);
void MessagesDeleted(const std::string& app_id);
void MessageSendError(const std::string& app_id,
const GCMClient::SendErrorDetails& send_error_details);
void GCMClientReady();
// Returns the handler for the given app.
GCMAppHandler* GetAppHandler(const std::string& app_id);
void RequestGCMStatisticsFinished(GCMClient::GCMStatistics stats);
// The profile which owns this object.
Profile* profile_;
// Flag to indicate if GCMClient is ready.
bool gcm_client_ready_;
// The username of the signed-in profile.
std::string username_;
content::NotificationRegistrar registrar_;
scoped_ptr<DelayedTaskController> delayed_task_controller_;
// For all the work occured in IO thread.
scoped_refptr<IOWorker> io_worker_;
// App handler map (from app_id to handler pointer).
// The handler is not owned.
GCMAppHandlerMap app_handlers_;
// The default handler when no app handler can be found in the map.
DefaultGCMAppHandler default_app_handler_;
// Callback map (from app_id to callback) for Register.
std::map<std::string, RegisterCallback> register_callbacks_;
// Callback map (from app_id to callback) for Unregister.
std::map<std::string, UnregisterCallback> unregister_callbacks_;
// Callback map (from <app_id, message_id> to callback) for Send.
std::map<std::pair<std::string, std::string>, SendCallback> send_callbacks_;
// Callback for RequestGCMStatistics.
RequestGCMStatisticsCallback request_gcm_statistics_callback_;
// Used to pass a weak pointer to the IO worker.
base::WeakPtrFactory<GCMProfileService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(GCMProfileService);
};
} // namespace gcm
#endif // CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
|