Chromium Code Reviews| 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/copresence/copresence_manager_impl.h" | 5 #include "components/copresence/copresence_manager_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "components/copresence/public/copresence_delegate.h" | 8 #include "components/copresence/public/copresence_delegate.h" |
| 9 #include "components/copresence/public/whispernet_client.h" | 9 #include "components/copresence/public/whispernet_client.h" |
| 10 #include "components/copresence/rpc/rpc_handler.h" | 10 #include "components/copresence/rpc/rpc_handler.h" |
| 11 | 11 |
| 12 namespace copresence { | 12 namespace copresence { |
| 13 | 13 |
| 14 PendingRequest::PendingRequest(const copresence::ReportRequest& report, | 14 PendingRequest::PendingRequest(const ReportRequest& report, |
| 15 const std::string app_id, | 15 const std::string& app_id, |
| 16 const std::string& auth_token, | |
| 16 const StatusCallback& callback) | 17 const StatusCallback& callback) |
| 17 : report(report), app_id(app_id), callback(callback) { | 18 : report(new ReportRequest(report)), |
| 18 } | 19 app_id(app_id), |
| 20 auth_token(auth_token), | |
| 21 callback(callback) {} | |
| 19 | 22 |
| 20 PendingRequest::~PendingRequest() { | 23 PendingRequest::~PendingRequest() {} |
| 21 } | |
| 22 | 24 |
| 23 // Public methods | 25 // Public methods |
| 24 | 26 |
| 25 CopresenceManagerImpl::~CopresenceManagerImpl() {} | 27 CopresenceManagerImpl::~CopresenceManagerImpl() { |
| 28 whispernet_init_callback_.Cancel(); | |
| 29 } | |
| 26 | 30 |
| 27 // Returns false if any operations were malformed. | 31 // Returns false if any operations were malformed. |
| 28 void CopresenceManagerImpl::ExecuteReportRequest( | 32 void CopresenceManagerImpl::ExecuteReportRequest( |
| 29 ReportRequest request, | 33 const ReportRequest& request, |
| 30 const std::string& app_id, | 34 const std::string& app_id, |
| 31 const StatusCallback& callback) { | 35 const StatusCallback& callback) { |
| 32 // Don't take on any more requests. We can't execute them since init failed. | 36 // If initialization has failed, reject all requests. |
| 33 if (init_failed_) { | 37 if (init_failed_) { |
| 34 callback.Run(FAIL); | 38 callback.Run(FAIL); |
| 35 return; | 39 return; |
| 36 } | 40 } |
| 37 | 41 |
| 38 DCHECK(rpc_handler_.get()); | 42 // Check if we are initialized enough to execute this request. |
| 43 // If we haven't seen this auth token yet, we need to register for it. | |
| 44 DCHECK(rpc_handler_); | |
| 45 if (!rpc_handler_->IsRegisteredForToken(delegate_->GetAuthToken())) { | |
| 46 pending_init_operations_++; | |
| 47 rpc_handler_->RegisterForToken( | |
|
rkc
2014/10/28 04:12:45
A cleaner design would be that we have each Regist
Charlie
2014/10/28 22:51:51
Yes. Added a TODO.
Rolling the RegisterDevice in
| |
| 48 delegate_->GetAuthToken(), | |
| 49 // The manager owns the RpcHandler, so this callback cannot outlive us. | |
| 50 base::Bind(&CopresenceManagerImpl::InitStepComplete, | |
| 51 base::Unretained(this), | |
| 52 "Device registration")); | |
|
rkc
2014/10/28 04:12:46
Adding the last few characters of the Auth token t
Charlie
2014/10/28 22:51:51
Done.
| |
| 53 } | |
| 54 | |
| 55 // Execute the request if possible, or queue it | |
| 56 // if initialization is still in progress. | |
| 39 if (pending_init_operations_) { | 57 if (pending_init_operations_) { |
| 40 pending_requests_queue_.push_back( | 58 pending_requests_queue_.push_back(make_scoped_ptr(new PendingRequest( |
| 41 PendingRequest(request, app_id, callback)); | 59 request, app_id, delegate_->GetAuthToken(), callback))); |
| 42 } else { | 60 } else { |
| 43 rpc_handler_->SendReportRequest( | 61 rpc_handler_->SendReportRequest( |
| 44 make_scoped_ptr(new copresence::ReportRequest(request)), | 62 make_scoped_ptr(new ReportRequest(request)), |
| 45 app_id, | 63 app_id, |
| 64 delegate_->GetAuthToken(), | |
| 46 callback); | 65 callback); |
| 47 } | 66 } |
| 48 } | 67 } |
| 49 | 68 |
| 50 // Private methods | 69 // Private methods |
| 51 | 70 |
| 52 CopresenceManagerImpl::CopresenceManagerImpl(CopresenceDelegate* delegate) | 71 CopresenceManagerImpl::CopresenceManagerImpl(CopresenceDelegate* delegate) |
| 53 : init_failed_(false), | 72 : init_failed_(false), |
| 54 pending_init_operations_(0), | 73 pending_init_operations_(0), |
| 55 delegate_(delegate) { | 74 delegate_(delegate), |
| 75 rpc_handler_(new RpcHandler(delegate)) { | |
| 56 DCHECK(delegate); | 76 DCHECK(delegate); |
| 57 } | 77 } |
| 58 | 78 |
| 59 void CopresenceManagerImpl::CompleteInitialization() { | 79 void CopresenceManagerImpl::CompleteInitialization() { |
| 60 if (pending_init_operations_) | 80 if (pending_init_operations_) |
| 61 return; | 81 return; |
| 62 | 82 |
| 63 DCHECK(rpc_handler_.get()); | 83 DCHECK(rpc_handler_.get()); |
| 64 if (!init_failed_) | 84 if (!init_failed_) |
| 65 rpc_handler_->ConnectToWhispernet(); | 85 rpc_handler_->ConnectToWhispernet(); |
| 66 | 86 |
| 67 for (PendingRequest& request : pending_requests_queue_) { | 87 for (scoped_ptr<PendingRequest>& request : pending_requests_queue_) { |
| 68 if (init_failed_) { | 88 if (init_failed_) { |
| 69 request.callback.Run(FAIL); | 89 request->callback.Run(FAIL); |
| 70 } else { | 90 } else { |
| 71 rpc_handler_->SendReportRequest( | 91 rpc_handler_->SendReportRequest( |
| 72 make_scoped_ptr(new copresence::ReportRequest(request.report)), | 92 request->report.Pass(), |
| 73 request.app_id, | 93 request->app_id, |
| 74 request.callback); | 94 request->auth_token, |
| 95 request->callback); | |
| 75 } | 96 } |
| 76 } | 97 } |
| 77 pending_requests_queue_.clear(); | 98 pending_requests_queue_.clear(); |
| 78 } | 99 } |
| 79 | 100 |
| 80 void CopresenceManagerImpl::InitStepComplete( | 101 void CopresenceManagerImpl::InitStepComplete( |
| 81 const std::string& step, bool success) { | 102 const std::string& step, bool success) { |
| 82 if (!success) { | 103 if (!success) { |
| 83 LOG(ERROR) << step << " failed!"; | 104 LOG(ERROR) << step << " failed!"; |
| 84 init_failed_ = true; | 105 init_failed_ = true; |
| 106 // TODO(ckehoe): Retry for registration failures. But maybe not here. | |
| 85 } | 107 } |
| 86 | 108 |
| 87 DVLOG(3) << "Init step: " << step << " complete."; | 109 DVLOG(3) << step << " complete."; |
| 110 DCHECK(pending_init_operations_ > 0); | |
| 88 pending_init_operations_--; | 111 pending_init_operations_--; |
| 89 CompleteInitialization(); | 112 CompleteInitialization(); |
| 90 } | 113 } |
| 91 | 114 |
| 115 // static | |
| 116 scoped_ptr<CopresenceManager> CopresenceManager::Create( | |
| 117 CopresenceDelegate* delegate) { | |
| 118 CopresenceManagerImpl* manager = new CopresenceManagerImpl(delegate); | |
| 119 | |
| 120 manager->pending_init_operations_++; | |
|
rkc
2014/10/28 04:12:45
Creating a derived class and directly accessing it
Charlie
2014/10/28 22:51:52
Yes, this has become simple enough that it can pro
| |
| 121 manager->whispernet_init_callback_.Reset( | |
| 122 base::Bind(&CopresenceManagerImpl::InitStepComplete, | |
| 123 // This callback will be canceled on manager's destruction, | |
| 124 // so unretained is safe to use here. | |
| 125 base::Unretained(manager), | |
| 126 "Whispernet proxy initialization")); | |
| 127 DCHECK(delegate->GetWhispernetClient()); | |
| 128 delegate->GetWhispernetClient()->Initialize( | |
| 129 manager->whispernet_init_callback_.callback()); | |
| 130 | |
| 131 return make_scoped_ptr<CopresenceManager>(manager); | |
| 132 } | |
| 133 | |
| 92 } // namespace copresence | 134 } // namespace copresence |
| OLD | NEW |