| 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 "components/gcm/gcm_driver.h" | 5 #include "components/gcm/gcm_driver_desktop.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
| 17 #include "base/threading/sequenced_worker_pool.h" | 17 #include "base/threading/sequenced_worker_pool.h" |
| 18 #include "components/gcm/gcm_app_handler.h" | 18 #include "components/gcm/gcm_app_handler.h" |
| 19 #include "components/gcm/gcm_client_factory.h" | 19 #include "components/gcm/gcm_client_factory.h" |
| 20 #include "google_apis/gaia/oauth2_token_service.h" | 20 #include "google_apis/gaia/oauth2_token_service.h" |
| 21 #include "google_apis/gcm/protocol/android_checkin.pb.h" | 21 #include "google_apis/gcm/protocol/android_checkin.pb.h" |
| 22 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
| 23 | 23 |
| 24 namespace gcm { | 24 namespace gcm { |
| 25 | 25 |
| 26 // Helper class to save tasks to run until we're ready to execute them. | 26 // Helper class to save tasks to run until we're ready to execute them. |
| 27 class GCMDriver::DelayedTaskController { | 27 class GCMDriverDesktop::DelayedTaskController { |
| 28 public: | 28 public: |
| 29 DelayedTaskController(); | 29 DelayedTaskController(); |
| 30 ~DelayedTaskController(); | 30 ~DelayedTaskController(); |
| 31 | 31 |
| 32 // Adds a task that will be invoked once we're ready. | 32 // Adds a task that will be invoked once we're ready. |
| 33 void AddTask(const base::Closure& task); | 33 void AddTask(const base::Closure& task); |
| 34 | 34 |
| 35 // Sets ready status. It is ready only when check-in is completed and | 35 // Sets ready status. It is ready only when check-in is completed and |
| 36 // the GCMClient is fully initialized. | 36 // the GCMClient is fully initialized. |
| 37 void SetReady(); | 37 void SetReady(); |
| 38 | 38 |
| 39 // Returns true if it is ready to perform tasks. | 39 // Returns true if it is ready to perform tasks. |
| 40 bool CanRunTaskWithoutDelay() const; | 40 bool CanRunTaskWithoutDelay() const; |
| 41 | 41 |
| 42 private: | 42 private: |
| 43 void RunTasks(); | 43 void RunTasks(); |
| 44 | 44 |
| 45 // Flag that indicates that GCM is ready. | 45 // Flag that indicates that GCM is ready. |
| 46 bool ready_; | 46 bool ready_; |
| 47 | 47 |
| 48 std::vector<base::Closure> delayed_tasks_; | 48 std::vector<base::Closure> delayed_tasks_; |
| 49 | 49 |
| 50 DISALLOW_COPY_AND_ASSIGN(DelayedTaskController); | 50 DISALLOW_COPY_AND_ASSIGN(DelayedTaskController); |
| 51 }; | 51 }; |
| 52 | 52 |
| 53 GCMDriver::DelayedTaskController::DelayedTaskController() : ready_(false) { | 53 GCMDriverDesktop::DelayedTaskController::DelayedTaskController() |
| 54 : ready_(false) { |
| 54 } | 55 } |
| 55 | 56 |
| 56 GCMDriver::DelayedTaskController::~DelayedTaskController() { | 57 GCMDriverDesktop::DelayedTaskController::~DelayedTaskController() { |
| 57 } | 58 } |
| 58 | 59 |
| 59 void GCMDriver::DelayedTaskController::AddTask(const base::Closure& task) { | 60 void GCMDriverDesktop::DelayedTaskController::AddTask( |
| 61 const base::Closure& task) { |
| 60 delayed_tasks_.push_back(task); | 62 delayed_tasks_.push_back(task); |
| 61 } | 63 } |
| 62 | 64 |
| 63 void GCMDriver::DelayedTaskController::SetReady() { | 65 void GCMDriverDesktop::DelayedTaskController::SetReady() { |
| 64 ready_ = true; | 66 ready_ = true; |
| 65 RunTasks(); | 67 RunTasks(); |
| 66 } | 68 } |
| 67 | 69 |
| 68 bool GCMDriver::DelayedTaskController::CanRunTaskWithoutDelay() const { | 70 bool GCMDriverDesktop::DelayedTaskController::CanRunTaskWithoutDelay() const { |
| 69 return ready_; | 71 return ready_; |
| 70 } | 72 } |
| 71 | 73 |
| 72 void GCMDriver::DelayedTaskController::RunTasks() { | 74 void GCMDriverDesktop::DelayedTaskController::RunTasks() { |
| 73 DCHECK(ready_); | 75 DCHECK(ready_); |
| 74 | 76 |
| 75 for (size_t i = 0; i < delayed_tasks_.size(); ++i) | 77 for (size_t i = 0; i < delayed_tasks_.size(); ++i) |
| 76 delayed_tasks_[i].Run(); | 78 delayed_tasks_[i].Run(); |
| 77 delayed_tasks_.clear(); | 79 delayed_tasks_.clear(); |
| 78 } | 80 } |
| 79 | 81 |
| 80 class GCMDriver::IOWorker : public GCMClient::Delegate { | 82 class GCMDriverDesktop::IOWorker : public GCMClient::Delegate { |
| 81 public: | 83 public: |
| 82 // Called on UI thread. | 84 // Called on UI thread. |
| 83 IOWorker(const scoped_refptr<base::MessageLoopProxy>& ui_thread, | 85 IOWorker(const scoped_refptr<base::MessageLoopProxy>& ui_thread, |
| 84 const scoped_refptr<base::MessageLoopProxy>& io_thread); | 86 const scoped_refptr<base::MessageLoopProxy>& io_thread); |
| 85 virtual ~IOWorker(); | 87 virtual ~IOWorker(); |
| 86 | 88 |
| 87 // Overridden from GCMClient::Delegate: | 89 // Overridden from GCMClient::Delegate: |
| 88 // Called on IO thread. | 90 // Called on IO thread. |
| 89 virtual void OnRegisterFinished(const std::string& app_id, | 91 virtual void OnRegisterFinished(const std::string& app_id, |
| 90 const std::string& registration_id, | 92 const std::string& registration_id, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 104 virtual void OnGCMReady() OVERRIDE; | 106 virtual void OnGCMReady() OVERRIDE; |
| 105 | 107 |
| 106 // Called on IO thread. | 108 // Called on IO thread. |
| 107 void Initialize( | 109 void Initialize( |
| 108 const checkin_proto::ChromeBuildProto& chrome_build_proto, | 110 const checkin_proto::ChromeBuildProto& chrome_build_proto, |
| 109 scoped_ptr<GCMClientFactory> gcm_client_factory, | 111 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 110 const base::FilePath& store_path, | 112 const base::FilePath& store_path, |
| 111 const std::vector<std::string>& account_ids, | 113 const std::vector<std::string>& account_ids, |
| 112 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 114 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
| 113 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); | 115 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); |
| 114 void Start(const base::WeakPtr<GCMDriver>& service); | 116 void Start(const base::WeakPtr<GCMDriverDesktop>& service); |
| 115 void Stop(); | 117 void Stop(); |
| 116 void CheckOut(); | 118 void CheckOut(); |
| 117 void Register(const std::string& app_id, | 119 void Register(const std::string& app_id, |
| 118 const std::vector<std::string>& sender_ids); | 120 const std::vector<std::string>& sender_ids); |
| 119 void Unregister(const std::string& app_id); | 121 void Unregister(const std::string& app_id); |
| 120 void Send(const std::string& app_id, | 122 void Send(const std::string& app_id, |
| 121 const std::string& receiver_id, | 123 const std::string& receiver_id, |
| 122 const GCMClient::OutgoingMessage& message); | 124 const GCMClient::OutgoingMessage& message); |
| 123 void GetGCMStatistics(bool clear_logs); | 125 void GetGCMStatistics(bool clear_logs); |
| 124 void SetGCMRecording(bool recording); | 126 void SetGCMRecording(bool recording); |
| 125 | 127 |
| 126 // For testing purpose. Can be called from UI thread. Use with care. | 128 // For testing purpose. Can be called from UI thread. Use with care. |
| 127 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); } | 129 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); } |
| 128 | 130 |
| 129 private: | 131 private: |
| 130 scoped_refptr<base::MessageLoopProxy> ui_thread_; | 132 scoped_refptr<base::MessageLoopProxy> ui_thread_; |
| 131 scoped_refptr<base::MessageLoopProxy> io_thread_; | 133 scoped_refptr<base::MessageLoopProxy> io_thread_; |
| 132 | 134 |
| 133 base::WeakPtr<GCMDriver> service_; | 135 base::WeakPtr<GCMDriverDesktop> service_; |
| 134 | 136 |
| 135 scoped_ptr<GCMClient> gcm_client_; | 137 scoped_ptr<GCMClient> gcm_client_; |
| 136 | 138 |
| 137 DISALLOW_COPY_AND_ASSIGN(IOWorker); | 139 DISALLOW_COPY_AND_ASSIGN(IOWorker); |
| 138 }; | 140 }; |
| 139 | 141 |
| 140 GCMDriver::IOWorker::IOWorker( | 142 GCMDriverDesktop::IOWorker::IOWorker( |
| 141 const scoped_refptr<base::MessageLoopProxy>& ui_thread, | 143 const scoped_refptr<base::MessageLoopProxy>& ui_thread, |
| 142 const scoped_refptr<base::MessageLoopProxy>& io_thread) | 144 const scoped_refptr<base::MessageLoopProxy>& io_thread) |
| 143 : ui_thread_(ui_thread), | 145 : ui_thread_(ui_thread), |
| 144 io_thread_(io_thread) { | 146 io_thread_(io_thread) { |
| 145 DCHECK(ui_thread_->BelongsToCurrentThread()); | 147 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 146 } | 148 } |
| 147 | 149 |
| 148 GCMDriver::IOWorker::~IOWorker() { | 150 GCMDriverDesktop::IOWorker::~IOWorker() { |
| 149 DCHECK(io_thread_->BelongsToCurrentThread()); | 151 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 150 } | 152 } |
| 151 | 153 |
| 152 void GCMDriver::IOWorker::Initialize( | 154 void GCMDriverDesktop::IOWorker::Initialize( |
| 153 const checkin_proto::ChromeBuildProto& chrome_build_proto, | 155 const checkin_proto::ChromeBuildProto& chrome_build_proto, |
| 154 scoped_ptr<GCMClientFactory> gcm_client_factory, | 156 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 155 const base::FilePath& store_path, | 157 const base::FilePath& store_path, |
| 156 const std::vector<std::string>& account_ids, | 158 const std::vector<std::string>& account_ids, |
| 157 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 159 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
| 158 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { | 160 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { |
| 159 DCHECK(io_thread_->BelongsToCurrentThread()); | 161 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 160 | 162 |
| 161 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); | 163 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); |
| 162 | 164 |
| 163 gcm_client_->Initialize(chrome_build_proto, | 165 gcm_client_->Initialize(chrome_build_proto, |
| 164 store_path, | 166 store_path, |
| 165 account_ids, | 167 account_ids, |
| 166 blocking_task_runner, | 168 blocking_task_runner, |
| 167 request_context, | 169 request_context, |
| 168 this); | 170 this); |
| 169 } | 171 } |
| 170 | 172 |
| 171 void GCMDriver::IOWorker::OnRegisterFinished( | 173 void GCMDriverDesktop::IOWorker::OnRegisterFinished( |
| 172 const std::string& app_id, | 174 const std::string& app_id, |
| 173 const std::string& registration_id, | 175 const std::string& registration_id, |
| 174 GCMClient::Result result) { | 176 GCMClient::Result result) { |
| 175 DCHECK(io_thread_->BelongsToCurrentThread()); | 177 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 176 | 178 |
| 177 ui_thread_->PostTask( | 179 ui_thread_->PostTask( |
| 178 FROM_HERE, | 180 FROM_HERE, |
| 179 base::Bind(&GCMDriver::RegisterFinished, service_, app_id, | 181 base::Bind(&GCMDriverDesktop::RegisterFinished, service_, app_id, |
| 180 registration_id, result)); | 182 registration_id, result)); |
| 181 } | 183 } |
| 182 | 184 |
| 183 void GCMDriver::IOWorker::OnUnregisterFinished(const std::string& app_id, | 185 void GCMDriverDesktop::IOWorker::OnUnregisterFinished( |
| 184 GCMClient::Result result) { | 186 const std::string& app_id, |
| 187 GCMClient::Result result) { |
| 185 DCHECK(io_thread_->BelongsToCurrentThread()); | 188 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 186 | 189 |
| 187 ui_thread_->PostTask( | 190 ui_thread_->PostTask( |
| 188 FROM_HERE, | 191 FROM_HERE, |
| 189 base::Bind(&GCMDriver::UnregisterFinished, service_, app_id, result)); | 192 base::Bind(&GCMDriverDesktop::UnregisterFinished, |
| 193 service_, |
| 194 app_id, |
| 195 result)); |
| 190 } | 196 } |
| 191 | 197 |
| 192 void GCMDriver::IOWorker::OnSendFinished(const std::string& app_id, | 198 void GCMDriverDesktop::IOWorker::OnSendFinished(const std::string& app_id, |
| 193 const std::string& message_id, | 199 const std::string& message_id, |
| 194 GCMClient::Result result) { | 200 GCMClient::Result result) { |
| 195 DCHECK(io_thread_->BelongsToCurrentThread()); | 201 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 196 | 202 |
| 197 ui_thread_->PostTask( | 203 ui_thread_->PostTask( |
| 198 FROM_HERE, | 204 FROM_HERE, |
| 199 base::Bind(&GCMDriver::SendFinished, service_, app_id, message_id, | 205 base::Bind(&GCMDriverDesktop::SendFinished, service_, app_id, message_id, |
| 200 result)); | 206 result)); |
| 201 } | 207 } |
| 202 | 208 |
| 203 void GCMDriver::IOWorker::OnMessageReceived( | 209 void GCMDriverDesktop::IOWorker::OnMessageReceived( |
| 204 const std::string& app_id, | 210 const std::string& app_id, |
| 205 const GCMClient::IncomingMessage& message) { | 211 const GCMClient::IncomingMessage& message) { |
| 206 DCHECK(io_thread_->BelongsToCurrentThread()); | 212 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 207 | 213 |
| 208 ui_thread_->PostTask( | 214 ui_thread_->PostTask( |
| 209 FROM_HERE, | 215 FROM_HERE, |
| 210 base::Bind(&GCMDriver::MessageReceived, service_, app_id, message)); | 216 base::Bind(&GCMDriverDesktop::MessageReceived, |
| 217 service_, |
| 218 app_id, |
| 219 message)); |
| 211 } | 220 } |
| 212 | 221 |
| 213 void GCMDriver::IOWorker::OnMessagesDeleted(const std::string& app_id) { | 222 void GCMDriverDesktop::IOWorker::OnMessagesDeleted(const std::string& app_id) { |
| 214 DCHECK(io_thread_->BelongsToCurrentThread()); | 223 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 215 | 224 |
| 216 ui_thread_->PostTask( | 225 ui_thread_->PostTask( |
| 217 FROM_HERE, | 226 FROM_HERE, |
| 218 base::Bind(&GCMDriver::MessagesDeleted, service_, app_id)); | 227 base::Bind(&GCMDriverDesktop::MessagesDeleted, service_, app_id)); |
| 219 } | 228 } |
| 220 | 229 |
| 221 void GCMDriver::IOWorker::OnMessageSendError( | 230 void GCMDriverDesktop::IOWorker::OnMessageSendError( |
| 222 const std::string& app_id, | 231 const std::string& app_id, |
| 223 const GCMClient::SendErrorDetails& send_error_details) { | 232 const GCMClient::SendErrorDetails& send_error_details) { |
| 224 DCHECK(io_thread_->BelongsToCurrentThread()); | 233 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 225 | 234 |
| 226 ui_thread_->PostTask( | 235 ui_thread_->PostTask( |
| 227 FROM_HERE, | 236 FROM_HERE, |
| 228 base::Bind(&GCMDriver::MessageSendError, service_, app_id, | 237 base::Bind(&GCMDriverDesktop::MessageSendError, service_, app_id, |
| 229 send_error_details)); | 238 send_error_details)); |
| 230 } | 239 } |
| 231 | 240 |
| 232 void GCMDriver::IOWorker::OnGCMReady() { | 241 void GCMDriverDesktop::IOWorker::OnGCMReady() { |
| 233 ui_thread_->PostTask( | 242 ui_thread_->PostTask( |
| 234 FROM_HERE, | 243 FROM_HERE, |
| 235 base::Bind(&GCMDriver::GCMClientReady, service_)); | 244 base::Bind(&GCMDriverDesktop::GCMClientReady, service_)); |
| 236 } | 245 } |
| 237 | 246 |
| 238 void GCMDriver::IOWorker::Start(const base::WeakPtr<GCMDriver>& service) { | 247 void GCMDriverDesktop::IOWorker::Start( |
| 248 const base::WeakPtr<GCMDriverDesktop>& service) { |
| 239 DCHECK(io_thread_->BelongsToCurrentThread()); | 249 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 240 | 250 |
| 241 service_ = service; | 251 service_ = service; |
| 242 gcm_client_->Start(); | 252 gcm_client_->Start(); |
| 243 } | 253 } |
| 244 | 254 |
| 245 void GCMDriver::IOWorker::Stop() { | 255 void GCMDriverDesktop::IOWorker::Stop() { |
| 246 DCHECK(io_thread_->BelongsToCurrentThread()); | 256 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 247 | 257 |
| 248 gcm_client_->Stop(); | 258 gcm_client_->Stop(); |
| 249 } | 259 } |
| 250 | 260 |
| 251 void GCMDriver::IOWorker::CheckOut() { | 261 void GCMDriverDesktop::IOWorker::CheckOut() { |
| 252 DCHECK(io_thread_->BelongsToCurrentThread()); | 262 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 253 | 263 |
| 254 gcm_client_->CheckOut(); | 264 gcm_client_->CheckOut(); |
| 255 | 265 |
| 256 // Note that we still need to keep GCMClient instance alive since the | 266 // Note that we still need to keep GCMClient instance alive since the |
| 257 // GCMDriver may check in again. | 267 // GCMDriverDesktop may check in again. |
| 258 } | 268 } |
| 259 | 269 |
| 260 void GCMDriver::IOWorker::Register( | 270 void GCMDriverDesktop::IOWorker::Register( |
| 261 const std::string& app_id, | 271 const std::string& app_id, |
| 262 const std::vector<std::string>& sender_ids) { | 272 const std::vector<std::string>& sender_ids) { |
| 263 DCHECK(io_thread_->BelongsToCurrentThread()); | 273 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 264 | 274 |
| 265 gcm_client_->Register(app_id, sender_ids); | 275 gcm_client_->Register(app_id, sender_ids); |
| 266 } | 276 } |
| 267 | 277 |
| 268 void GCMDriver::IOWorker::Unregister(const std::string& app_id) { | 278 void GCMDriverDesktop::IOWorker::Unregister(const std::string& app_id) { |
| 269 DCHECK(io_thread_->BelongsToCurrentThread()); | 279 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 270 | 280 |
| 271 gcm_client_->Unregister(app_id); | 281 gcm_client_->Unregister(app_id); |
| 272 } | 282 } |
| 273 | 283 |
| 274 void GCMDriver::IOWorker::Send(const std::string& app_id, | 284 void GCMDriverDesktop::IOWorker::Send( |
| 275 const std::string& receiver_id, | 285 const std::string& app_id, |
| 276 const GCMClient::OutgoingMessage& message) { | 286 const std::string& receiver_id, |
| 287 const GCMClient::OutgoingMessage& message) { |
| 277 DCHECK(io_thread_->BelongsToCurrentThread()); | 288 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 278 | 289 |
| 279 gcm_client_->Send(app_id, receiver_id, message); | 290 gcm_client_->Send(app_id, receiver_id, message); |
| 280 } | 291 } |
| 281 | 292 |
| 282 void GCMDriver::IOWorker::GetGCMStatistics(bool clear_logs) { | 293 void GCMDriverDesktop::IOWorker::GetGCMStatistics(bool clear_logs) { |
| 283 DCHECK(io_thread_->BelongsToCurrentThread()); | 294 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 284 gcm::GCMClient::GCMStatistics stats; | 295 gcm::GCMClient::GCMStatistics stats; |
| 285 | 296 |
| 286 if (gcm_client_.get()) { | 297 if (gcm_client_.get()) { |
| 287 if (clear_logs) | 298 if (clear_logs) |
| 288 gcm_client_->ClearActivityLogs(); | 299 gcm_client_->ClearActivityLogs(); |
| 289 stats = gcm_client_->GetStatistics(); | 300 stats = gcm_client_->GetStatistics(); |
| 290 } | 301 } |
| 291 | 302 |
| 292 ui_thread_->PostTask( | 303 ui_thread_->PostTask( |
| 293 FROM_HERE, | 304 FROM_HERE, |
| 294 base::Bind(&GCMDriver::GetGCMStatisticsFinished, service_, stats)); | 305 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats)); |
| 295 } | 306 } |
| 296 | 307 |
| 297 void GCMDriver::IOWorker::SetGCMRecording(bool recording) { | 308 void GCMDriverDesktop::IOWorker::SetGCMRecording(bool recording) { |
| 298 DCHECK(io_thread_->BelongsToCurrentThread()); | 309 DCHECK(io_thread_->BelongsToCurrentThread()); |
| 299 gcm::GCMClient::GCMStatistics stats; | 310 gcm::GCMClient::GCMStatistics stats; |
| 300 | 311 |
| 301 if (gcm_client_.get()) { | 312 if (gcm_client_.get()) { |
| 302 gcm_client_->SetRecording(recording); | 313 gcm_client_->SetRecording(recording); |
| 303 stats = gcm_client_->GetStatistics(); | 314 stats = gcm_client_->GetStatistics(); |
| 304 stats.gcm_client_created = true; | 315 stats.gcm_client_created = true; |
| 305 } | 316 } |
| 306 | 317 |
| 307 ui_thread_->PostTask( | 318 ui_thread_->PostTask( |
| 308 FROM_HERE, | 319 FROM_HERE, |
| 309 base::Bind(&GCMDriver::GetGCMStatisticsFinished, service_, stats)); | 320 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats)); |
| 310 } | 321 } |
| 311 | 322 |
| 312 GCMDriver::GCMDriver( | 323 GCMDriverDesktop::GCMDriverDesktop( |
| 313 const checkin_proto::ChromeBuildProto& chrome_build_proto, | 324 const checkin_proto::ChromeBuildProto& chrome_build_proto, |
| 314 scoped_ptr<GCMClientFactory> gcm_client_factory, | 325 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 315 scoped_ptr<IdentityProvider> identity_provider, | 326 scoped_ptr<IdentityProvider> identity_provider, |
| 316 const base::FilePath& store_path, | 327 const base::FilePath& store_path, |
| 317 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 328 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
| 318 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, | 329 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, |
| 319 const scoped_refptr<base::MessageLoopProxy>& ui_thread, | 330 const scoped_refptr<base::MessageLoopProxy>& ui_thread, |
| 320 const scoped_refptr<base::MessageLoopProxy>& io_thread) | 331 const scoped_refptr<base::MessageLoopProxy>& io_thread) |
| 321 : identity_provider_(identity_provider.Pass()), | 332 : GCMDriver(ui_thread), |
| 322 ui_thread_(ui_thread), | 333 identity_provider_(identity_provider.Pass()), |
| 323 io_thread_(io_thread), | 334 io_thread_(io_thread), |
| 324 gcm_enabled_(true), | 335 gcm_enabled_(true), |
| 325 gcm_client_ready_(false), | 336 gcm_client_ready_(false), |
| 326 weak_ptr_factory_(this) { | 337 weak_ptr_factory_(this) { |
| 327 // Get the list of available accounts. | 338 // Get the list of available accounts. |
| 328 std::vector<std::string> account_ids; | 339 std::vector<std::string> account_ids; |
| 329 #if !defined(OS_ANDROID) | 340 #if !defined(OS_ANDROID) |
| 330 account_ids = identity_provider_->GetTokenService()->GetAccounts(); | 341 account_ids = identity_provider_->GetTokenService()->GetAccounts(); |
| 331 #endif | 342 #endif |
| 332 | 343 |
| 333 // Create and initialize the GCMClient. Note that this does not initiate the | 344 // Create and initialize the GCMClient. Note that this does not initiate the |
| 334 // GCM check-in. | 345 // GCM check-in. |
| 335 DCHECK(!io_worker_); | 346 DCHECK(!io_worker_); |
| 336 io_worker_.reset(new IOWorker(ui_thread, io_thread)); | 347 io_worker_.reset(new IOWorker(ui_thread, io_thread)); |
| 337 io_thread_->PostTask( | 348 io_thread_->PostTask( |
| 338 FROM_HERE, | 349 FROM_HERE, |
| 339 base::Bind(&GCMDriver::IOWorker::Initialize, | 350 base::Bind(&GCMDriverDesktop::IOWorker::Initialize, |
| 340 base::Unretained(io_worker_.get()), | 351 base::Unretained(io_worker_.get()), |
| 341 chrome_build_proto, | 352 chrome_build_proto, |
| 342 base::Passed(&gcm_client_factory), | 353 base::Passed(&gcm_client_factory), |
| 343 store_path, | 354 store_path, |
| 344 account_ids, | 355 account_ids, |
| 345 request_context, | 356 request_context, |
| 346 blocking_task_runner)); | 357 blocking_task_runner)); |
| 347 | 358 |
| 348 identity_provider_->AddObserver(this); | 359 identity_provider_->AddObserver(this); |
| 349 } | 360 } |
| 350 | 361 |
| 351 GCMDriver::GCMDriver() | 362 GCMDriverDesktop::GCMDriverDesktop() |
| 352 : gcm_enabled_(true), | 363 : gcm_enabled_(true), |
| 353 gcm_client_ready_(false), | 364 gcm_client_ready_(false), |
| 354 weak_ptr_factory_(this) { | 365 weak_ptr_factory_(this) { |
| 355 } | 366 } |
| 356 | 367 |
| 357 GCMDriver::~GCMDriver() { | 368 GCMDriverDesktop::~GCMDriverDesktop() { |
| 358 } | 369 } |
| 359 | 370 |
| 360 void GCMDriver::Enable() { | 371 void GCMDriverDesktop::Enable() { |
| 361 DCHECK(ui_thread_->BelongsToCurrentThread()); | 372 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 362 | 373 |
| 363 if (gcm_enabled_) | 374 if (gcm_enabled_) |
| 364 return; | 375 return; |
| 365 gcm_enabled_ = true; | 376 gcm_enabled_ = true; |
| 366 | 377 |
| 367 EnsureStarted(); | 378 EnsureStarted(); |
| 368 } | 379 } |
| 369 | 380 |
| 370 void GCMDriver::Disable() { | 381 void GCMDriverDesktop::Disable() { |
| 371 DCHECK(ui_thread_->BelongsToCurrentThread()); | 382 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 372 | 383 |
| 373 if (!gcm_enabled_) | 384 if (!gcm_enabled_) |
| 374 return; | 385 return; |
| 375 gcm_enabled_ = false; | 386 gcm_enabled_ = false; |
| 376 | 387 |
| 377 Stop(); | 388 Stop(); |
| 378 } | 389 } |
| 379 | 390 |
| 380 void GCMDriver::Shutdown() { | 391 void GCMDriverDesktop::Shutdown() { |
| 381 DCHECK(ui_thread_->BelongsToCurrentThread()); | 392 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 382 identity_provider_->RemoveObserver(this); | 393 identity_provider_->RemoveObserver(this); |
| 383 for (GCMAppHandlerMap::const_iterator iter = app_handlers_.begin(); | 394 GCMDriver::Shutdown(); |
| 384 iter != app_handlers_.end(); ++iter) { | |
| 385 iter->second->ShutdownHandler(); | |
| 386 } | |
| 387 app_handlers_.clear(); | |
| 388 io_thread_->DeleteSoon(FROM_HERE, io_worker_.release()); | 395 io_thread_->DeleteSoon(FROM_HERE, io_worker_.release()); |
| 389 } | 396 } |
| 390 | 397 |
| 391 void GCMDriver::AddAppHandler(const std::string& app_id, | 398 void GCMDriverDesktop::AddAppHandler(const std::string& app_id, |
| 392 GCMAppHandler* handler) { | 399 GCMAppHandler* handler) { |
| 393 DCHECK(ui_thread_->BelongsToCurrentThread()); | 400 GCMDriver::AddAppHandler(app_id, handler); |
| 394 DCHECK(!app_id.empty()); | |
| 395 DCHECK(handler); | |
| 396 | |
| 397 app_handlers_[app_id] = handler; | |
| 398 | 401 |
| 399 // Ensures that the GCM service is started when there is an interest. | 402 // Ensures that the GCM service is started when there is an interest. |
| 400 EnsureStarted(); | 403 EnsureStarted(); |
| 401 } | 404 } |
| 402 | 405 |
| 403 void GCMDriver::RemoveAppHandler(const std::string& app_id) { | 406 void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) { |
| 404 DCHECK(ui_thread_->BelongsToCurrentThread()); | 407 GCMDriver::RemoveAppHandler(app_id); |
| 405 DCHECK(!app_id.empty()); | |
| 406 | |
| 407 app_handlers_.erase(app_id); | |
| 408 | 408 |
| 409 // Stops the GCM service when no app intends to consume it. | 409 // Stops the GCM service when no app intends to consume it. |
| 410 if (app_handlers_.empty()) | 410 if (app_handlers().empty()) |
| 411 Stop(); | 411 Stop(); |
| 412 } | 412 } |
| 413 | 413 |
| 414 void GCMDriver::Register(const std::string& app_id, | 414 void GCMDriverDesktop::Register(const std::string& app_id, |
| 415 const std::vector<std::string>& sender_ids, | 415 const std::vector<std::string>& sender_ids, |
| 416 const RegisterCallback& callback) { | 416 const RegisterCallback& callback) { |
| 417 DCHECK(ui_thread_->BelongsToCurrentThread()); | 417 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 418 DCHECK(!app_id.empty()); | 418 DCHECK(!app_id.empty()); |
| 419 DCHECK(!sender_ids.empty()); | 419 DCHECK(!sender_ids.empty()); |
| 420 DCHECK(!callback.is_null()); | 420 DCHECK(!callback.is_null()); |
| 421 | 421 |
| 422 GCMClient::Result result = EnsureStarted(); | 422 GCMClient::Result result = EnsureStarted(); |
| 423 if (result != GCMClient::SUCCESS) { | 423 if (result != GCMClient::SUCCESS) { |
| 424 callback.Run(std::string(), result); | 424 callback.Run(std::string(), result); |
| 425 return; | 425 return; |
| 426 } | 426 } |
| 427 | 427 |
| 428 // If previous un/register operation is still in progress, bail out. | 428 // If previous un/register operation is still in progress, bail out. |
| 429 if (IsAsyncOperationPending(app_id)) { | 429 if (IsAsyncOperationPending(app_id)) { |
| 430 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); | 430 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); |
| 431 return; | 431 return; |
| 432 } | 432 } |
| 433 | 433 |
| 434 register_callbacks_[app_id] = callback; | 434 register_callbacks_[app_id] = callback; |
| 435 | 435 |
| 436 // Delay the register operation until GCMClient is ready. | 436 // Delay the register operation until GCMClient is ready. |
| 437 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { | 437 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { |
| 438 delayed_task_controller_->AddTask(base::Bind(&GCMDriver::DoRegister, | 438 delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoRegister, |
| 439 weak_ptr_factory_.GetWeakPtr(), | 439 weak_ptr_factory_.GetWeakPtr(), |
| 440 app_id, | 440 app_id, |
| 441 sender_ids)); | 441 sender_ids)); |
| 442 return; | 442 return; |
| 443 } | 443 } |
| 444 | 444 |
| 445 DoRegister(app_id, sender_ids); | 445 DoRegister(app_id, sender_ids); |
| 446 } | 446 } |
| 447 | 447 |
| 448 void GCMDriver::DoRegister(const std::string& app_id, | 448 void GCMDriverDesktop::DoRegister(const std::string& app_id, |
| 449 const std::vector<std::string>& sender_ids) { | 449 const std::vector<std::string>& sender_ids) { |
| 450 DCHECK(ui_thread_->BelongsToCurrentThread()); | 450 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 451 std::map<std::string, RegisterCallback>::iterator callback_iter = | 451 std::map<std::string, RegisterCallback>::iterator callback_iter = |
| 452 register_callbacks_.find(app_id); | 452 register_callbacks_.find(app_id); |
| 453 if (callback_iter == register_callbacks_.end()) { | 453 if (callback_iter == register_callbacks_.end()) { |
| 454 // The callback could have been removed when the app is uninstalled. | 454 // The callback could have been removed when the app is uninstalled. |
| 455 return; | 455 return; |
| 456 } | 456 } |
| 457 | 457 |
| 458 // Normalize the sender IDs by making them sorted. | 458 // Normalize the sender IDs by making them sorted. |
| 459 std::vector<std::string> normalized_sender_ids = sender_ids; | 459 std::vector<std::string> normalized_sender_ids = sender_ids; |
| 460 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end()); | 460 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end()); |
| 461 | 461 |
| 462 io_thread_->PostTask( | 462 io_thread_->PostTask( |
| 463 FROM_HERE, | 463 FROM_HERE, |
| 464 base::Bind(&GCMDriver::IOWorker::Register, | 464 base::Bind(&GCMDriverDesktop::IOWorker::Register, |
| 465 base::Unretained(io_worker_.get()), | 465 base::Unretained(io_worker_.get()), |
| 466 app_id, | 466 app_id, |
| 467 normalized_sender_ids)); | 467 normalized_sender_ids)); |
| 468 } | 468 } |
| 469 | 469 |
| 470 void GCMDriver::Unregister(const std::string& app_id, | 470 void GCMDriverDesktop::Unregister(const std::string& app_id, |
| 471 const UnregisterCallback& callback) { | 471 const UnregisterCallback& callback) { |
| 472 DCHECK(ui_thread_->BelongsToCurrentThread()); | 472 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 473 DCHECK(!app_id.empty()); | 473 DCHECK(!app_id.empty()); |
| 474 DCHECK(!callback.is_null()); | 474 DCHECK(!callback.is_null()); |
| 475 | 475 |
| 476 GCMClient::Result result = EnsureStarted(); | 476 GCMClient::Result result = EnsureStarted(); |
| 477 if (result != GCMClient::SUCCESS) { | 477 if (result != GCMClient::SUCCESS) { |
| 478 callback.Run(result); | 478 callback.Run(result); |
| 479 return; | 479 return; |
| 480 } | 480 } |
| 481 | 481 |
| 482 // If previous un/register operation is still in progress, bail out. | 482 // If previous un/register operation is still in progress, bail out. |
| 483 if (IsAsyncOperationPending(app_id)) { | 483 if (IsAsyncOperationPending(app_id)) { |
| 484 callback.Run(GCMClient::ASYNC_OPERATION_PENDING); | 484 callback.Run(GCMClient::ASYNC_OPERATION_PENDING); |
| 485 return; | 485 return; |
| 486 } | 486 } |
| 487 | 487 |
| 488 unregister_callbacks_[app_id] = callback; | 488 unregister_callbacks_[app_id] = callback; |
| 489 | 489 |
| 490 // Delay the unregister operation until GCMClient is ready. | 490 // Delay the unregister operation until GCMClient is ready. |
| 491 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { | 491 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { |
| 492 delayed_task_controller_->AddTask(base::Bind(&GCMDriver::DoUnregister, | 492 delayed_task_controller_->AddTask( |
| 493 weak_ptr_factory_.GetWeakPtr(), | 493 base::Bind(&GCMDriverDesktop::DoUnregister, |
| 494 app_id)); | 494 weak_ptr_factory_.GetWeakPtr(), |
| 495 app_id)); |
| 495 return; | 496 return; |
| 496 } | 497 } |
| 497 | 498 |
| 498 DoUnregister(app_id); | 499 DoUnregister(app_id); |
| 499 } | 500 } |
| 500 | 501 |
| 501 void GCMDriver::DoUnregister(const std::string& app_id) { | 502 void GCMDriverDesktop::DoUnregister(const std::string& app_id) { |
| 502 DCHECK(ui_thread_->BelongsToCurrentThread()); | 503 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 503 | 504 |
| 504 // Ask the server to unregister it. There could be a small chance that the | 505 // Ask the server to unregister it. There could be a small chance that the |
| 505 // unregister request fails. If this occurs, it does not bring any harm since | 506 // unregister request fails. If this occurs, it does not bring any harm since |
| 506 // we simply reject the messages/events received from the server. | 507 // we simply reject the messages/events received from the server. |
| 507 io_thread_->PostTask( | 508 io_thread_->PostTask( |
| 508 FROM_HERE, | 509 FROM_HERE, |
| 509 base::Bind(&GCMDriver::IOWorker::Unregister, | 510 base::Bind(&GCMDriverDesktop::IOWorker::Unregister, |
| 510 base::Unretained(io_worker_.get()), | 511 base::Unretained(io_worker_.get()), |
| 511 app_id)); | 512 app_id)); |
| 512 } | 513 } |
| 513 | 514 |
| 514 void GCMDriver::Send(const std::string& app_id, | 515 void GCMDriverDesktop::Send(const std::string& app_id, |
| 515 const std::string& receiver_id, | 516 const std::string& receiver_id, |
| 516 const GCMClient::OutgoingMessage& message, | 517 const GCMClient::OutgoingMessage& message, |
| 517 const SendCallback& callback) { | 518 const SendCallback& callback) { |
| 518 DCHECK(ui_thread_->BelongsToCurrentThread()); | 519 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 519 DCHECK(!app_id.empty()); | 520 DCHECK(!app_id.empty()); |
| 520 DCHECK(!receiver_id.empty()); | 521 DCHECK(!receiver_id.empty()); |
| 521 DCHECK(!callback.is_null()); | 522 DCHECK(!callback.is_null()); |
| 522 | 523 |
| 523 GCMClient::Result result = EnsureStarted(); | 524 GCMClient::Result result = EnsureStarted(); |
| 524 if (result != GCMClient::SUCCESS) { | 525 if (result != GCMClient::SUCCESS) { |
| 525 callback.Run(std::string(), result); | 526 callback.Run(std::string(), result); |
| 526 return; | 527 return; |
| 527 } | 528 } |
| 528 | 529 |
| 529 // If the message with send ID is still in progress, bail out. | 530 // If the message with send ID is still in progress, bail out. |
| 530 std::pair<std::string, std::string> key(app_id, message.id); | 531 std::pair<std::string, std::string> key(app_id, message.id); |
| 531 if (send_callbacks_.find(key) != send_callbacks_.end()) { | 532 if (send_callbacks_.find(key) != send_callbacks_.end()) { |
| 532 callback.Run(message.id, GCMClient::INVALID_PARAMETER); | 533 callback.Run(message.id, GCMClient::INVALID_PARAMETER); |
| 533 return; | 534 return; |
| 534 } | 535 } |
| 535 | 536 |
| 536 send_callbacks_[key] = callback; | 537 send_callbacks_[key] = callback; |
| 537 | 538 |
| 538 // Delay the send operation until all GCMClient is ready. | 539 // Delay the send operation until all GCMClient is ready. |
| 539 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { | 540 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) { |
| 540 delayed_task_controller_->AddTask(base::Bind(&GCMDriver::DoSend, | 541 delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoSend, |
| 541 weak_ptr_factory_.GetWeakPtr(), | 542 weak_ptr_factory_.GetWeakPtr(), |
| 542 app_id, | 543 app_id, |
| 543 receiver_id, | 544 receiver_id, |
| 544 message)); | 545 message)); |
| 545 return; | 546 return; |
| 546 } | 547 } |
| 547 | 548 |
| 548 DoSend(app_id, receiver_id, message); | 549 DoSend(app_id, receiver_id, message); |
| 549 } | 550 } |
| 550 | 551 |
| 551 void GCMDriver::DoSend(const std::string& app_id, | 552 void GCMDriverDesktop::DoSend(const std::string& app_id, |
| 552 const std::string& receiver_id, | 553 const std::string& receiver_id, |
| 553 const GCMClient::OutgoingMessage& message) { | 554 const GCMClient::OutgoingMessage& message) { |
| 554 DCHECK(ui_thread_->BelongsToCurrentThread()); | 555 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 555 io_thread_->PostTask( | 556 io_thread_->PostTask( |
| 556 FROM_HERE, | 557 FROM_HERE, |
| 557 base::Bind(&GCMDriver::IOWorker::Send, | 558 base::Bind(&GCMDriverDesktop::IOWorker::Send, |
| 558 base::Unretained(io_worker_.get()), | 559 base::Unretained(io_worker_.get()), |
| 559 app_id, | 560 app_id, |
| 560 receiver_id, | 561 receiver_id, |
| 561 message)); | 562 message)); |
| 562 } | 563 } |
| 563 | 564 |
| 564 GCMClient* GCMDriver::GetGCMClientForTesting() const { | 565 GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const { |
| 565 DCHECK(ui_thread_->BelongsToCurrentThread()); | 566 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 566 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; | 567 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; |
| 567 } | 568 } |
| 568 | 569 |
| 569 bool GCMDriver::IsStarted() const { | 570 bool GCMDriverDesktop::IsStarted() const { |
| 570 DCHECK(ui_thread_->BelongsToCurrentThread()); | 571 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 571 return !account_id_.empty(); | 572 return !account_id_.empty(); |
| 572 } | 573 } |
| 573 | 574 |
| 574 bool GCMDriver::IsGCMClientReady() const { | 575 bool GCMDriverDesktop::IsGCMClientReady() const { |
| 575 DCHECK(ui_thread_->BelongsToCurrentThread()); | 576 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 576 return gcm_client_ready_; | 577 return gcm_client_ready_; |
| 577 } | 578 } |
| 578 | 579 |
| 579 void GCMDriver::GetGCMStatistics(GetGCMStatisticsCallback callback, | 580 void GCMDriverDesktop::GetGCMStatistics(GetGCMStatisticsCallback callback, |
| 580 bool clear_logs) { | 581 bool clear_logs) { |
| 581 DCHECK(ui_thread_->BelongsToCurrentThread()); | 582 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 582 DCHECK(!callback.is_null()); | 583 DCHECK(!callback.is_null()); |
| 583 | 584 |
| 584 request_gcm_statistics_callback_ = callback; | 585 request_gcm_statistics_callback_ = callback; |
| 585 io_thread_->PostTask( | 586 io_thread_->PostTask( |
| 586 FROM_HERE, | 587 FROM_HERE, |
| 587 base::Bind(&GCMDriver::IOWorker::GetGCMStatistics, | 588 base::Bind(&GCMDriverDesktop::IOWorker::GetGCMStatistics, |
| 588 base::Unretained(io_worker_.get()), | 589 base::Unretained(io_worker_.get()), |
| 589 clear_logs)); | 590 clear_logs)); |
| 590 } | 591 } |
| 591 | 592 |
| 592 void GCMDriver::SetGCMRecording(GetGCMStatisticsCallback callback, | 593 void GCMDriverDesktop::SetGCMRecording(GetGCMStatisticsCallback callback, |
| 593 bool recording) { | 594 bool recording) { |
| 594 DCHECK(ui_thread_->BelongsToCurrentThread()); | 595 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 595 | 596 |
| 596 request_gcm_statistics_callback_ = callback; | 597 request_gcm_statistics_callback_ = callback; |
| 597 io_thread_->PostTask( | 598 io_thread_->PostTask( |
| 598 FROM_HERE, | 599 FROM_HERE, |
| 599 base::Bind(&GCMDriver::IOWorker::SetGCMRecording, | 600 base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording, |
| 600 base::Unretained(io_worker_.get()), | 601 base::Unretained(io_worker_.get()), |
| 601 recording)); | 602 recording)); |
| 602 } | 603 } |
| 603 | 604 |
| 604 void GCMDriver::OnActiveAccountLogin() { | 605 void GCMDriverDesktop::OnActiveAccountLogin() { |
| 605 EnsureStarted(); | 606 EnsureStarted(); |
| 606 } | 607 } |
| 607 | 608 |
| 608 void GCMDriver::OnActiveAccountLogout() { | 609 void GCMDriverDesktop::OnActiveAccountLogout() { |
| 609 CheckOut(); | 610 CheckOut(); |
| 610 } | 611 } |
| 611 | 612 |
| 612 GCMClient::Result GCMDriver::EnsureStarted() { | 613 GCMClient::Result GCMDriverDesktop::EnsureStarted() { |
| 613 DCHECK(ui_thread_->BelongsToCurrentThread()); | 614 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 614 | 615 |
| 615 // Is GCM enabled? | 616 // Is GCM enabled? |
| 616 if (!gcm_enabled_) | 617 if (!gcm_enabled_) |
| 617 return GCMClient::GCM_DISABLED; | 618 return GCMClient::GCM_DISABLED; |
| 618 | 619 |
| 619 // Has any app requested the service? | 620 // Has any app requested the service? |
| 620 if (app_handlers_.empty()) | 621 if (app_handlers().empty()) |
| 621 return GCMClient::UNKNOWN_ERROR; | 622 return GCMClient::UNKNOWN_ERROR; |
| 622 | 623 |
| 623 // Can we get an account ID from the identity provider? | 624 // Can we get an account ID from the identity provider? |
| 624 const std::string account_id = identity_provider_->GetActiveAccountId(); | 625 const std::string account_id = identity_provider_->GetActiveAccountId(); |
| 625 if (account_id.empty()) | 626 if (account_id.empty()) |
| 626 return GCMClient::NOT_SIGNED_IN; | 627 return GCMClient::NOT_SIGNED_IN; |
| 627 | 628 |
| 628 // CheckIn could be called more than once when: | 629 // CheckIn could be called more than once when: |
| 629 // 1) The password changes. | 630 // 1) The password changes. |
| 630 // 2) Register/send function calls it to ensure CheckIn is done. | 631 // 2) Register/send function calls it to ensure CheckIn is done. |
| 631 if (account_id_ == account_id) | 632 if (account_id_ == account_id) |
| 632 return GCMClient::SUCCESS; | 633 return GCMClient::SUCCESS; |
| 633 account_id_ = account_id; | 634 account_id_ = account_id; |
| 634 | 635 |
| 635 DCHECK(!delayed_task_controller_); | 636 DCHECK(!delayed_task_controller_); |
| 636 delayed_task_controller_.reset(new DelayedTaskController); | 637 delayed_task_controller_.reset(new DelayedTaskController); |
| 637 | 638 |
| 638 // This will load the data from the gcm store and trigger the check-in if | 639 // This will load the data from the gcm store and trigger the check-in if |
| 639 // the persisted check-in info is not found. | 640 // the persisted check-in info is not found. |
| 640 // Note that we need to pass weak pointer again since the existing weak | 641 // Note that we need to pass weak pointer again since the existing weak |
| 641 // pointer in IOWorker might have been invalidated when check-out occurs. | 642 // pointer in IOWorker might have been invalidated when check-out occurs. |
| 642 io_thread_->PostTask( | 643 io_thread_->PostTask( |
| 643 FROM_HERE, | 644 FROM_HERE, |
| 644 base::Bind(&GCMDriver::IOWorker::Start, | 645 base::Bind(&GCMDriverDesktop::IOWorker::Start, |
| 645 base::Unretained(io_worker_.get()), | 646 base::Unretained(io_worker_.get()), |
| 646 weak_ptr_factory_.GetWeakPtr())); | 647 weak_ptr_factory_.GetWeakPtr())); |
| 647 | 648 |
| 648 return GCMClient::SUCCESS; | 649 return GCMClient::SUCCESS; |
| 649 } | 650 } |
| 650 | 651 |
| 651 void GCMDriver::Stop() { | 652 void GCMDriverDesktop::Stop() { |
| 652 // No need to stop GCM service if not started yet. | 653 // No need to stop GCM service if not started yet. |
| 653 if (account_id_.empty()) | 654 if (account_id_.empty()) |
| 654 return; | 655 return; |
| 655 | 656 |
| 656 RemoveCachedData(); | 657 RemoveCachedData(); |
| 657 | 658 |
| 658 io_thread_->PostTask( | 659 io_thread_->PostTask( |
| 659 FROM_HERE, | 660 FROM_HERE, |
| 660 base::Bind(&GCMDriver::IOWorker::Stop, | 661 base::Bind(&GCMDriverDesktop::IOWorker::Stop, |
| 661 base::Unretained(io_worker_.get()))); | 662 base::Unretained(io_worker_.get()))); |
| 662 } | 663 } |
| 663 | 664 |
| 664 void GCMDriver::RemoveCachedData() { | 665 void GCMDriverDesktop::RemoveCachedData() { |
| 665 DCHECK(ui_thread_->BelongsToCurrentThread()); | 666 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 666 // Remove all the queued tasks since they no longer make sense after | 667 // Remove all the queued tasks since they no longer make sense after |
| 667 // GCM service is stopped. | 668 // GCM service is stopped. |
| 668 weak_ptr_factory_.InvalidateWeakPtrs(); | 669 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 669 | 670 |
| 670 account_id_.clear(); | 671 account_id_.clear(); |
| 671 gcm_client_ready_ = false; | 672 gcm_client_ready_ = false; |
| 672 delayed_task_controller_.reset(); | 673 delayed_task_controller_.reset(); |
| 673 register_callbacks_.clear(); | 674 register_callbacks_.clear(); |
| 674 send_callbacks_.clear(); | 675 send_callbacks_.clear(); |
| 675 } | 676 } |
| 676 | 677 |
| 677 void GCMDriver::CheckOut() { | 678 void GCMDriverDesktop::CheckOut() { |
| 678 DCHECK(ui_thread_->BelongsToCurrentThread()); | 679 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 679 | 680 |
| 680 // We still proceed with the check-out logic even if the check-in is not | 681 // We still proceed with the check-out logic even if the check-in is not |
| 681 // initiated in the current session. This will make sure that all the | 682 // initiated in the current session. This will make sure that all the |
| 682 // persisted data written previously will get purged. | 683 // persisted data written previously will get purged. |
| 683 | 684 |
| 684 RemoveCachedData(); | 685 RemoveCachedData(); |
| 685 | 686 |
| 686 io_thread_->PostTask( | 687 io_thread_->PostTask( |
| 687 FROM_HERE, | 688 FROM_HERE, |
| 688 base::Bind(&GCMDriver::IOWorker::CheckOut, | 689 base::Bind(&GCMDriverDesktop::IOWorker::CheckOut, |
| 689 base::Unretained(io_worker_.get()))); | 690 base::Unretained(io_worker_.get()))); |
| 690 } | 691 } |
| 691 | 692 |
| 692 bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const { | 693 bool GCMDriverDesktop::IsAsyncOperationPending( |
| 694 const std::string& app_id) const { |
| 693 DCHECK(ui_thread_->BelongsToCurrentThread()); | 695 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 694 return register_callbacks_.find(app_id) != register_callbacks_.end() || | 696 return register_callbacks_.find(app_id) != register_callbacks_.end() || |
| 695 unregister_callbacks_.find(app_id) != unregister_callbacks_.end(); | 697 unregister_callbacks_.find(app_id) != unregister_callbacks_.end(); |
| 696 } | 698 } |
| 697 | 699 |
| 698 void GCMDriver::RegisterFinished(const std::string& app_id, | 700 void GCMDriverDesktop::RegisterFinished(const std::string& app_id, |
| 699 const std::string& registration_id, | 701 const std::string& registration_id, |
| 700 GCMClient::Result result) { | 702 GCMClient::Result result) { |
| 701 DCHECK(ui_thread_->BelongsToCurrentThread()); | 703 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 702 | 704 |
| 703 std::map<std::string, RegisterCallback>::iterator callback_iter = | 705 std::map<std::string, RegisterCallback>::iterator callback_iter = |
| 704 register_callbacks_.find(app_id); | 706 register_callbacks_.find(app_id); |
| 705 if (callback_iter == register_callbacks_.end()) { | 707 if (callback_iter == register_callbacks_.end()) { |
| 706 // The callback could have been removed when the app is uninstalled. | 708 // The callback could have been removed when the app is uninstalled. |
| 707 return; | 709 return; |
| 708 } | 710 } |
| 709 | 711 |
| 710 RegisterCallback callback = callback_iter->second; | 712 RegisterCallback callback = callback_iter->second; |
| 711 register_callbacks_.erase(callback_iter); | 713 register_callbacks_.erase(callback_iter); |
| 712 callback.Run(registration_id, result); | 714 callback.Run(registration_id, result); |
| 713 } | 715 } |
| 714 | 716 |
| 715 void GCMDriver::UnregisterFinished(const std::string& app_id, | 717 void GCMDriverDesktop::UnregisterFinished(const std::string& app_id, |
| 716 GCMClient::Result result) { | 718 GCMClient::Result result) { |
| 717 DCHECK(ui_thread_->BelongsToCurrentThread()); | 719 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 718 | 720 |
| 719 std::map<std::string, UnregisterCallback>::iterator callback_iter = | 721 std::map<std::string, UnregisterCallback>::iterator callback_iter = |
| 720 unregister_callbacks_.find(app_id); | 722 unregister_callbacks_.find(app_id); |
| 721 if (callback_iter == unregister_callbacks_.end()) | 723 if (callback_iter == unregister_callbacks_.end()) |
| 722 return; | 724 return; |
| 723 | 725 |
| 724 UnregisterCallback callback = callback_iter->second; | 726 UnregisterCallback callback = callback_iter->second; |
| 725 unregister_callbacks_.erase(callback_iter); | 727 unregister_callbacks_.erase(callback_iter); |
| 726 callback.Run(result); | 728 callback.Run(result); |
| 727 } | 729 } |
| 728 | 730 |
| 729 void GCMDriver::SendFinished(const std::string& app_id, | 731 void GCMDriverDesktop::SendFinished(const std::string& app_id, |
| 730 const std::string& message_id, | 732 const std::string& message_id, |
| 731 GCMClient::Result result) { | 733 GCMClient::Result result) { |
| 732 DCHECK(ui_thread_->BelongsToCurrentThread()); | 734 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 733 | 735 |
| 734 std::map<std::pair<std::string, std::string>, SendCallback>::iterator | 736 std::map<std::pair<std::string, std::string>, SendCallback>::iterator |
| 735 callback_iter = send_callbacks_.find( | 737 callback_iter = send_callbacks_.find( |
| 736 std::pair<std::string, std::string>(app_id, message_id)); | 738 std::pair<std::string, std::string>(app_id, message_id)); |
| 737 if (callback_iter == send_callbacks_.end()) { | 739 if (callback_iter == send_callbacks_.end()) { |
| 738 // The callback could have been removed when the app is uninstalled. | 740 // The callback could have been removed when the app is uninstalled. |
| 739 return; | 741 return; |
| 740 } | 742 } |
| 741 | 743 |
| 742 SendCallback callback = callback_iter->second; | 744 SendCallback callback = callback_iter->second; |
| 743 send_callbacks_.erase(callback_iter); | 745 send_callbacks_.erase(callback_iter); |
| 744 callback.Run(message_id, result); | 746 callback.Run(message_id, result); |
| 745 } | 747 } |
| 746 | 748 |
| 747 void GCMDriver::MessageReceived(const std::string& app_id, | 749 void GCMDriverDesktop::MessageReceived(const std::string& app_id, |
| 748 GCMClient::IncomingMessage message) { | 750 GCMClient::IncomingMessage message) { |
| 749 DCHECK(ui_thread_->BelongsToCurrentThread()); | 751 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 750 | 752 |
| 751 // Drop the event if signed out. | 753 // Drop the event if signed out. |
| 752 if (account_id_.empty()) | 754 if (account_id_.empty()) |
| 753 return; | 755 return; |
| 754 | 756 |
| 755 GetAppHandler(app_id)->OnMessage(app_id, message); | 757 GetAppHandler(app_id)->OnMessage(app_id, message); |
| 756 } | 758 } |
| 757 | 759 |
| 758 void GCMDriver::MessagesDeleted(const std::string& app_id) { | 760 void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) { |
| 759 DCHECK(ui_thread_->BelongsToCurrentThread()); | 761 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 760 | 762 |
| 761 // Drop the event if signed out. | 763 // Drop the event if signed out. |
| 762 if (account_id_.empty()) | 764 if (account_id_.empty()) |
| 763 return; | 765 return; |
| 764 | 766 |
| 765 GetAppHandler(app_id)->OnMessagesDeleted(app_id); | 767 GetAppHandler(app_id)->OnMessagesDeleted(app_id); |
| 766 } | 768 } |
| 767 | 769 |
| 768 void GCMDriver::MessageSendError( | 770 void GCMDriverDesktop::MessageSendError( |
| 769 const std::string& app_id, | 771 const std::string& app_id, |
| 770 const GCMClient::SendErrorDetails& send_error_details) { | 772 const GCMClient::SendErrorDetails& send_error_details) { |
| 771 DCHECK(ui_thread_->BelongsToCurrentThread()); | 773 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 772 | 774 |
| 773 // Drop the event if signed out. | 775 // Drop the event if signed out. |
| 774 if (account_id_.empty()) | 776 if (account_id_.empty()) |
| 775 return; | 777 return; |
| 776 | 778 |
| 777 GetAppHandler(app_id)->OnSendError(app_id, send_error_details); | 779 GetAppHandler(app_id)->OnSendError(app_id, send_error_details); |
| 778 } | 780 } |
| 779 | 781 |
| 780 void GCMDriver::GCMClientReady() { | 782 void GCMDriverDesktop::GCMClientReady() { |
| 781 DCHECK(ui_thread_->BelongsToCurrentThread()); | 783 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 782 | 784 |
| 783 if (gcm_client_ready_) | 785 if (gcm_client_ready_) |
| 784 return; | 786 return; |
| 785 gcm_client_ready_ = true; | 787 gcm_client_ready_ = true; |
| 786 | 788 |
| 787 delayed_task_controller_->SetReady(); | 789 delayed_task_controller_->SetReady(); |
| 788 } | 790 } |
| 789 | 791 |
| 790 GCMAppHandler* GCMDriver::GetAppHandler(const std::string& app_id) { | 792 GCMAppHandler* GCMDriverDesktop::GetAppHandler(const std::string& app_id) { |
| 791 DCHECK(ui_thread_->BelongsToCurrentThread()); | 793 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 792 | 794 |
| 793 std::map<std::string, GCMAppHandler*>::const_iterator iter = | 795 GCMAppHandlerMap::const_iterator iter = app_handlers().find(app_id); |
| 794 app_handlers_.find(app_id); | 796 return iter == app_handlers().end() ? &default_app_handler_ : iter->second; |
| 795 return iter == app_handlers_.end() ? &default_app_handler_ : iter->second; | |
| 796 } | 797 } |
| 797 | 798 |
| 798 void GCMDriver::GetGCMStatisticsFinished(GCMClient::GCMStatistics stats) { | 799 void GCMDriverDesktop::GetGCMStatisticsFinished( |
| 800 GCMClient::GCMStatistics stats) { |
| 799 DCHECK(ui_thread_->BelongsToCurrentThread()); | 801 DCHECK(ui_thread_->BelongsToCurrentThread()); |
| 800 request_gcm_statistics_callback_.Run(stats); | 802 request_gcm_statistics_callback_.Run(stats); |
| 801 } | 803 } |
| 802 | 804 |
| 803 std::string GCMDriver::SignedInUserName() const { | 805 std::string GCMDriverDesktop::SignedInUserName() const { |
| 804 if (IsStarted()) | 806 if (IsStarted()) |
| 805 return identity_provider_->GetActiveUsername(); | 807 return identity_provider_->GetActiveUsername(); |
| 806 return std::string(); | 808 return std::string(); |
| 807 } | 809 } |
| 808 | 810 |
| 809 } // namespace gcm | 811 } // namespace gcm |
| OLD | NEW |