Index: components/copresence/copresence_manager_impl.cc |
diff --git a/components/copresence/copresence_manager_impl.cc b/components/copresence/copresence_manager_impl.cc |
index 342ed1999a184cb59788612f951bb25175595bc7..e5f6afb3cb8421a72a7a0fb4a35c89ad95af76d7 100644 |
--- a/components/copresence/copresence_manager_impl.cc |
+++ b/components/copresence/copresence_manager_impl.cc |
@@ -5,44 +5,84 @@ |
#include "components/copresence/copresence_manager_impl.h" |
#include "base/bind.h" |
+#include "base/strings/stringprintf.h" |
#include "components/copresence/public/copresence_delegate.h" |
#include "components/copresence/public/whispernet_client.h" |
#include "components/copresence/rpc/rpc_handler.h" |
+namespace { |
+ |
+// Number of characters of suffix to log for auth tokens |
+const int kTokenSuffix = 5; |
+ |
+} // namespace |
+ |
namespace copresence { |
-PendingRequest::PendingRequest(const copresence::ReportRequest& report, |
- const std::string app_id, |
+PendingRequest::PendingRequest(const ReportRequest& report, |
+ const std::string& app_id, |
+ const std::string& auth_token, |
const StatusCallback& callback) |
- : report(report), app_id(app_id), callback(callback) { |
-} |
+ : report(new ReportRequest(report)), |
+ app_id(app_id), |
+ auth_token(auth_token), |
+ callback(callback) {} |
+ |
+PendingRequest::~PendingRequest() {} |
-PendingRequest::~PendingRequest() { |
+// static |
+scoped_ptr<CopresenceManager> CopresenceManager::Create( |
+ CopresenceDelegate* delegate) { |
+ return make_scoped_ptr(new CopresenceManagerImpl(delegate)); |
} |
+ |
// Public methods |
-CopresenceManagerImpl::~CopresenceManagerImpl() {} |
+CopresenceManagerImpl::~CopresenceManagerImpl() { |
+ whispernet_init_callback_.Cancel(); |
+} |
// Returns false if any operations were malformed. |
void CopresenceManagerImpl::ExecuteReportRequest( |
- ReportRequest request, |
+ const ReportRequest& request, |
const std::string& app_id, |
const StatusCallback& callback) { |
- // Don't take on any more requests. We can't execute them since init failed. |
+ // If initialization has failed, reject all requests. |
if (init_failed_) { |
callback.Run(FAIL); |
return; |
} |
- DCHECK(rpc_handler_.get()); |
+ // Check if we are initialized enough to execute this request. |
+ // If we haven't seen this auth token yet, we need to register for it. |
+ // TODO(ckehoe): Queue per device ID instead of globally. |
+ DCHECK(rpc_handler_); |
+ const std::string& auth_token = delegate_->GetAuthToken(); |
+ if (!rpc_handler_->IsRegisteredForToken(auth_token)) { |
+ std::string token_str = auth_token.empty() ? "(anonymous)" : |
+ base::StringPrintf("(token ...%s)", |
+ auth_token.substr(auth_token.length() - kTokenSuffix, |
+ kTokenSuffix).c_str()); |
+ rpc_handler_->RegisterForToken( |
+ auth_token, |
+ // The manager owns the RpcHandler, so this callback cannot outlive us. |
+ base::Bind(&CopresenceManagerImpl::InitStepComplete, |
+ base::Unretained(this), |
+ "Device registration " + token_str)); |
+ pending_init_operations_++; |
+ } |
+ |
+ // Execute the request if possible, or queue it |
+ // if initialization is still in progress. |
if (pending_init_operations_) { |
pending_requests_queue_.push_back( |
- PendingRequest(request, app_id, callback)); |
+ new PendingRequest(request, app_id, auth_token, callback)); |
} else { |
rpc_handler_->SendReportRequest( |
- make_scoped_ptr(new copresence::ReportRequest(request)), |
+ make_scoped_ptr(new ReportRequest(request)), |
app_id, |
+ auth_token, |
callback); |
} |
} |
@@ -51,9 +91,20 @@ void CopresenceManagerImpl::ExecuteReportRequest( |
CopresenceManagerImpl::CopresenceManagerImpl(CopresenceDelegate* delegate) |
: init_failed_(false), |
+ // This callback gets cancelled when we are destroyed. |
+ whispernet_init_callback_( |
+ base::Bind(&CopresenceManagerImpl::InitStepComplete, |
+ base::Unretained(this), |
+ "Whispernet proxy initialization")), |
pending_init_operations_(0), |
- delegate_(delegate) { |
+ delegate_(delegate), |
+ rpc_handler_(new RpcHandler(delegate)) { |
DCHECK(delegate); |
+ DCHECK(delegate->GetWhispernetClient()); |
+ |
+ delegate->GetWhispernetClient()->Initialize( |
+ whispernet_init_callback_.callback()); |
+ pending_init_operations_++; |
} |
void CopresenceManagerImpl::CompleteInitialization() { |
@@ -64,14 +115,17 @@ void CopresenceManagerImpl::CompleteInitialization() { |
if (!init_failed_) |
rpc_handler_->ConnectToWhispernet(); |
- for (PendingRequest& request : pending_requests_queue_) { |
+ // Not const because SendReportRequest takes ownership of the ReportRequests. |
+ // This is ok though, as the entire queue is deleted afterwards. |
+ for (PendingRequest* request : pending_requests_queue_) { |
if (init_failed_) { |
- request.callback.Run(FAIL); |
+ request->callback.Run(FAIL); |
} else { |
rpc_handler_->SendReportRequest( |
- make_scoped_ptr(new copresence::ReportRequest(request.report)), |
- request.app_id, |
- request.callback); |
+ request->report.Pass(), |
+ request->app_id, |
+ request->auth_token, |
+ request->callback); |
} |
} |
pending_requests_queue_.clear(); |
@@ -82,9 +136,11 @@ void CopresenceManagerImpl::InitStepComplete( |
if (!success) { |
LOG(ERROR) << step << " failed!"; |
init_failed_ = true; |
+ // TODO(ckehoe): Retry for registration failures. But maybe not here. |
} |
- DVLOG(3) << "Init step: " << step << " complete."; |
+ DVLOG(3) << step << " complete."; |
+ DCHECK(pending_init_operations_ > 0); |
pending_init_operations_--; |
CompleteInitialization(); |
} |