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 |