1 // Copyright (c) 2013 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 #ifndef CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
6 #define CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
17 #include "content/public/browser/notification_observer.h"
18 #include "content/public/browser/notification_registrar.h"
19 #include "google_apis/gcm/gcm_client.h"
27 namespace extensions {
31 namespace user_prefs {
32 class PrefRegistrySyncable;
37 class GCMClientFactory;
39 class GCMProfileServiceTestConsumer;
41 // Acts as a bridge between GCM API and GCMClient layer. It is profile based.
42 class GCMProfileService : public BrowserContextKeyedService,
43 public content::NotificationObserver {
45 typedef base::Callback<void(const std::string& registration_id,
46 GCMClient::Result result)> RegisterCallback;
47 typedef base::Callback<void(const std::string& message_id,
48 GCMClient::Result result)> SendCallback;
50 // For testing purpose.
51 class TestingDelegate {
53 virtual GCMEventRouter* GetEventRouter() const = 0;
56 // Returns true if the GCM support is enabled.
57 static bool IsGCMEnabled(Profile* profile);
59 // Register profile-specific prefs for GCM.
60 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
62 explicit GCMProfileService(Profile* profile);
63 virtual ~GCMProfileService();
65 void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory);
67 // Registers |sender_id| for an app. A registration ID will be returned by
69 // |app_id|: application ID.
70 // |cert|: SHA-1 of public key of the application, in base16 format.
71 // |sender_ids|: list of IDs of the servers that are allowed to send the
72 // messages to the application. These IDs are assigned by the
73 // Google API Console.
74 // |callback|: to be called once the asynchronous operation is done.
75 virtual void Register(const std::string& app_id,
76 const std::vector<std::string>& sender_ids,
77 const std::string& cert,
78 RegisterCallback callback);
80 // Sends a message to a given receiver.
81 // |app_id|: application ID.
82 // |receiver_id|: registration ID of the receiver party.
83 // |message|: message to be sent.
84 // |callback|: to be called once the asynchronous operation is done.
85 virtual void Send(const std::string& app_id,
86 const std::string& receiver_id,
87 const GCMClient::OutgoingMessage& message,
88 SendCallback callback);
90 // For testing purpose.
91 void set_testing_delegate(TestingDelegate* testing_delegate) {
92 testing_delegate_ = testing_delegate;
96 // Flag that could be set by the testing code to enable GCM. Otherwise,
97 // tests from official build will fail.
98 static bool enable_gcm_for_testing_;
101 friend class GCMProfileServiceTestConsumer;
103 class DelayedTaskController;
106 struct RegistrationInfo {
109 bool IsValid() const;
111 std::vector<std::string> sender_ids;
112 std::string registration_id;
115 // Overridden from content::NotificationObserver:
116 virtual void Observe(int type,
117 const content::NotificationSource& source,
118 const content::NotificationDetails& details) OVERRIDE;
120 // Checks in with GCM by creating and initializing GCMClient when the profile
121 // has been signed in.
122 void CheckIn(const std::string& username);
124 // Checks out of GCM when the profile has been signed out. This will erase
125 // all the cached and persisted data.
128 // Resets the GCMClient instance. This is called when the profile is being
130 void ResetGCMClient();
132 // Ensures that the app is ready for GCM functions and events.
133 void EnsureAppReady(const std::string& app_id);
135 // Unregisters an app from using the GCM after it has been uninstalled.
136 void Unregister(const std::string& app_id);
138 void DoRegister(const std::string& app_id,
139 const std::vector<std::string>& sender_ids,
140 const std::string& cert);
141 void DoSend(const std::string& app_id,
142 const std::string& receiver_id,
143 const GCMClient::OutgoingMessage& message);
145 // Callbacks posted from IO thread to UI thread.
146 void RegisterFinished(const std::string& app_id,
147 const std::string& registration_id,
148 GCMClient::Result result);
149 void SendFinished(const std::string& app_id,
150 const std::string& message_id,
151 GCMClient::Result result);
152 void MessageReceived(const std::string& app_id,
153 GCMClient::IncomingMessage message);
154 void MessagesDeleted(const std::string& app_id);
155 void MessageSendError(const std::string& app_id,
156 const std::string& message_id,
157 GCMClient::Result result);
158 void FinishInitializationOnUI(bool ready);
159 void GCMClientReady();
161 // Returns the event router to fire the event for the given app.
162 GCMEventRouter* GetEventRouter(const std::string& app_id) const;
164 // Used to persist the IDs of registered apps.
165 void ReadRegisteredAppIDs();
166 void WriteRegisteredAppIDs();
168 // Used to persist registration info into the app's state store.
169 void DeleteRegistrationInfo(const std::string& app_id);
170 void WriteRegistrationInfo(const std::string& app_id);
171 void ReadRegistrationInfo(const std::string& app_id);
172 void ReadRegistrationInfoFinished(const std::string& app_id,
173 scoped_ptr<base::Value> value);
174 bool ParsePersistedRegistrationInfo(scoped_ptr<base::Value> value,
175 RegistrationInfo* registration_info);
177 // Returns the key used to identify the registration info saved into the
178 // app's state store. Used for testing purpose.
179 static const char* GetPersistentRegisterKeyForTesting();
181 // The profile which owns this object.
184 // Used to creat the GCMClient instance.
185 scoped_ptr<GCMClientFactory> gcm_client_factory_;
187 // Flag to indicate if GCMClient is ready.
188 bool gcm_client_ready_;
190 // The username of the signed-in profile.
191 std::string username_;
193 content::NotificationRegistrar registrar_;
195 scoped_ptr<DelayedTaskController> delayed_task_controller_;
197 // For all the work occured in IO thread.
198 scoped_refptr<IOWorker> io_worker_;
200 // Callback map (from app_id to callback) for Register.
201 std::map<std::string, RegisterCallback> register_callbacks_;
203 // Callback map (from <app_id, message_id> to callback) for Send.
204 std::map<std::pair<std::string, std::string>, SendCallback> send_callbacks_;
206 // Map from app_id to registration info (sender ids & registration ID).
207 typedef std::map<std::string, RegistrationInfo> RegistrationInfoMap;
208 RegistrationInfoMap registration_info_map_;
210 // Event router to talk with JS API.
211 #if !defined(OS_ANDROID)
212 scoped_ptr<GCMEventRouter> js_event_router_;
215 // For testing purpose.
216 TestingDelegate* testing_delegate_;
218 // Used to pass a weak pointer to the IO worker.
219 base::WeakPtrFactory<GCMProfileService> weak_ptr_factory_;
221 DISALLOW_COPY_AND_ASSIGN(GCMProfileService);
226 #endif // CHROME_BROWSER_SERVICES_GCM_GCM_PROFILE_SERVICE_H_