Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: components/copresence/rpc/rpc_handler.cc

Issue 671573003: Adding support for authenticated copresence calls (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing memory error Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/rpc/rpc_handler.h" 5 #include "components/copresence/rpc/rpc_handler.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 const char kRegisterDeviceRpcName[] = "registerdevice"; 54 const char kRegisterDeviceRpcName[] = "registerdevice";
55 const char kDefaultCopresenceServer[] = 55 const char kDefaultCopresenceServer[] =
56 "https://www.googleapis.com/copresence/v2/copresence"; 56 "https://www.googleapis.com/copresence/v2/copresence";
57 57
58 // Logging 58 // Logging
59 59
60 // Checks for a copresence error. If there is one, logs it and returns true. 60 // Checks for a copresence error. If there is one, logs it and returns true.
61 bool CopresenceErrorLogged(const Status& status) { 61 bool CopresenceErrorLogged(const Status& status) {
62 if (status.code() != OK) { 62 if (status.code() != OK) {
63 LOG(ERROR) << "Copresence error code " << status.code() 63 LOG(ERROR) << "Copresence error code " << status.code()
64 << (status.message().empty() ? std::string() : 64 << (status.message().empty() ? "" : ": " + status.message());
65 ": " + status.message());
66 } 65 }
67 return status.code() != OK; 66 return status.code() != OK;
68 } 67 }
69 68
70 void LogIfErrorStatus(const util::error::Code& code, 69 void LogIfErrorStatus(const util::error::Code& code,
71 const std::string& context) { 70 const std::string& context) {
72 LOG_IF(ERROR, code != util::error::OK) 71 LOG_IF(ERROR, code != util::error::OK)
73 << context << " error " << code << ". See " 72 << context << " error " << code << ". See "
74 << "cs/google3/util/task/codes.proto for more info."; 73 << "cs/google3/util/task/codes.proto for more info.";
75 } 74 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 ClientVersion* CreateVersion(const std::string& client, 128 ClientVersion* CreateVersion(const std::string& client,
130 const std::string& version_name) { 129 const std::string& version_name) {
131 ClientVersion* version = new ClientVersion; 130 ClientVersion* version = new ClientVersion;
132 131
133 version->set_client(client); 132 version->set_client(client);
134 version->set_version_name(version_name); 133 version->set_version_name(version_name);
135 134
136 return version; 135 return version;
137 } 136 }
138 137
139 void AddTokenToRequest(ReportRequest* request, const AudioToken& token) { 138 void AddTokenToRequest(const AudioToken& token, ReportRequest* request) {
140 TokenObservation* token_observation = 139 TokenObservation* token_observation =
141 request->mutable_update_signals_request()->add_token_observation(); 140 request->mutable_update_signals_request()->add_token_observation();
142 token_observation->set_token_id(ToUrlSafe(token.token)); 141 token_observation->set_token_id(ToUrlSafe(token.token));
143 142
144 TokenSignals* signals = token_observation->add_signals(); 143 TokenSignals* signals = token_observation->add_signals();
145 signals->set_medium(token.audible ? AUDIO_AUDIBLE_DTMF 144 signals->set_medium(token.audible ? AUDIO_AUDIBLE_DTMF
146 : AUDIO_ULTRASOUND_PASSBAND); 145 : AUDIO_ULTRASOUND_PASSBAND);
147 signals->set_observed_time_millis(base::Time::Now().ToJsTime()); 146 signals->set_observed_time_millis(base::Time::Now().ToJsTime());
148 } 147 }
149 148
(...skipping 15 matching lines...) Expand all
165 } 164 }
166 165
167 if (delegate_ && delegate_->GetWhispernetClient()) { 166 if (delegate_ && delegate_->GetWhispernetClient()) {
168 delegate_->GetWhispernetClient()->RegisterTokensCallback( 167 delegate_->GetWhispernetClient()->RegisterTokensCallback(
169 WhispernetClient::TokensCallback()); 168 WhispernetClient::TokensCallback());
170 delegate_->GetWhispernetClient()->RegisterSamplesCallback( 169 delegate_->GetWhispernetClient()->RegisterSamplesCallback(
171 WhispernetClient::SamplesCallback()); 170 WhispernetClient::SamplesCallback());
172 } 171 }
173 } 172 }
174 173
175 void RpcHandler::Initialize(const SuccessCallback& init_done_callback) { 174 void RpcHandler::RegisterForToken(const std::string& auth_token,
175 const SuccessCallback& init_done_callback) {
176 if (IsRegisteredForToken(auth_token)) {
177 LOG(WARNING) << "Attempted re-registration for the same auth token.";
178 init_done_callback.Run(true);
179 return;
180 }
176 scoped_ptr<RegisterDeviceRequest> request(new RegisterDeviceRequest); 181 scoped_ptr<RegisterDeviceRequest> request(new RegisterDeviceRequest);
177 DCHECK(device_id_.empty());
178 182
179 request->mutable_push_service()->set_service(PUSH_SERVICE_NONE); 183 request->mutable_push_service()->set_service(PUSH_SERVICE_NONE);
180 Identity* identity = 184
181 request->mutable_device_identifiers()->mutable_registrant(); 185 DVLOG(2) << "Sending " << (auth_token.empty() ? "anonymous" : "authenticated")
182 identity->set_type(CHROME); 186 << " registration to server.";
183 identity->set_chrome_id(base::GenerateGUID()); 187
188 // Only identify as a Chrome device if we're in anonymous mode.
189 // Authenticated calls come from a "GAIA device".
190 if (auth_token.empty()) {
191 Identity* identity =
192 request->mutable_device_identifiers()->mutable_registrant();
193 identity->set_type(CHROME);
194 identity->set_chrome_id(base::GenerateGUID());
195 }
196
184 SendServerRequest( 197 SendServerRequest(
185 kRegisterDeviceRpcName, 198 kRegisterDeviceRpcName,
186 std::string(), 199 std::string(), // device ID
200 std::string(), // app ID
201 auth_token,
187 request.Pass(), 202 request.Pass(),
188 base::Bind(&RpcHandler::RegisterResponseHandler, 203 base::Bind(&RpcHandler::RegisterResponseHandler,
189 // On destruction, this request will be cancelled. 204 // On destruction, this request will be cancelled.
190 base::Unretained(this), 205 base::Unretained(this),
191 init_done_callback)); 206 init_done_callback,
207 auth_token));
192 } 208 }
193 209
194 void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request) { 210 bool RpcHandler::IsRegisteredForToken(const std::string& auth_token) const {
195 SendReportRequest(request.Pass(), std::string(), StatusCallback()); 211 return device_id_by_auth_token_.find(auth_token) !=
212 device_id_by_auth_token_.end();
213 }
214
215 void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request,
216 const std::string& auth_token) {
217 SendReportRequest(request.Pass(),
218 std::string(),
219 auth_token,
220 StatusCallback());
196 } 221 }
197 222
198 void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request, 223 void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request,
199 const std::string& app_id, 224 const std::string& app_id,
225 const std::string& auth_token,
200 const StatusCallback& status_callback) { 226 const StatusCallback& status_callback) {
201 DCHECK(request.get()); 227 DCHECK(request.get());
202 DCHECK(!device_id_.empty()) 228 auto registration_entry = device_id_by_auth_token_.find(auth_token);
203 << "RpcHandler::Initialize() must complete successfully " 229 DCHECK(registration_entry != device_id_by_auth_token_.end())
204 << "before other RpcHandler methods are called."; 230 << "RegisterForToken() must complete successfully "
231 << "for new tokens before calling SendReportRequest().";
205 232
206 DVLOG(3) << "Sending report request to server."; 233 DVLOG(3) << "Sending ReportRequest to server.";
207 234
208 // If we are unpublishing or unsubscribing, we need to stop those publish or 235 // If we are unpublishing or unsubscribing, we need to stop those publish or
209 // subscribes right away, we don't need to wait for the server to tell us. 236 // subscribes right away, we don't need to wait for the server to tell us.
210 ProcessRemovedOperations(*request); 237 ProcessRemovedOperations(*request);
211 238
212 request->mutable_update_signals_request()->set_allocated_state( 239 request->mutable_update_signals_request()->set_allocated_state(
213 GetDeviceCapabilities(*request).release()); 240 GetDeviceCapabilities(*request).release());
214 241
215 AddPlayingTokens(request.get()); 242 AddPlayingTokens(request.get());
216 243
217 SendServerRequest(kReportRequestRpcName, 244 SendServerRequest(kReportRequestRpcName,
245 registration_entry->second,
218 app_id, 246 app_id,
247 auth_token,
219 request.Pass(), 248 request.Pass(),
220 // On destruction, this request will be cancelled. 249 // On destruction, this request will be cancelled.
221 base::Bind(&RpcHandler::ReportResponseHandler, 250 base::Bind(&RpcHandler::ReportResponseHandler,
222 base::Unretained(this), 251 base::Unretained(this),
223 status_callback)); 252 status_callback));
224 } 253 }
225 254
226 void RpcHandler::ReportTokens(const std::vector<AudioToken>& tokens) { 255 void RpcHandler::ReportTokens(const std::vector<AudioToken>& tokens) {
227 DCHECK(!tokens.empty()); 256 DCHECK(!tokens.empty());
228 257
229 scoped_ptr<ReportRequest> request(new ReportRequest); 258 if (device_id_by_auth_token_.empty()) {
259 VLOG(2) << "Skipping token reporting because no device IDs are registered";
260 return;
261 }
262
263 // Construct the ReportRequest.
264 ReportRequest request;
230 for (const AudioToken& token : tokens) { 265 for (const AudioToken& token : tokens) {
231 if (invalid_audio_token_cache_.HasKey(ToUrlSafe(token.token))) 266 if (invalid_audio_token_cache_.HasKey(ToUrlSafe(token.token)))
232 continue; 267 continue;
233 DVLOG(3) << "Sending token " << token.token << " to server."; 268 DVLOG(3) << "Sending token " << token.token << " to server under "
234 AddTokenToRequest(request.get(), token); 269 << device_id_by_auth_token_.size() << " device ID(s)";
270 AddTokenToRequest(token, &request);
235 } 271 }
236 SendReportRequest(request.Pass()); 272
273 // Report under all active tokens.
274 for (const auto& registration : device_id_by_auth_token_) {
275 SendReportRequest(make_scoped_ptr(new ReportRequest(request)),
276 registration.first);
277 }
237 } 278 }
238 279
239 void RpcHandler::ConnectToWhispernet() { 280 void RpcHandler::ConnectToWhispernet() {
281 // Check if we are already connected.
282 if (directive_handler_)
283 return;
284
240 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient(); 285 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient();
241 286
242 // |directive_handler_| will be destructed with us, so unretained is safe. 287 // |directive_handler_| will be destructed with us, so unretained is safe.
243 directive_handler_.reset(new DirectiveHandler); 288 directive_handler_.reset(new DirectiveHandler);
244 directive_handler_->Initialize( 289 directive_handler_->Initialize(
245 base::Bind(&WhispernetClient::DecodeSamples, 290 base::Bind(&WhispernetClient::DecodeSamples,
246 base::Unretained(whispernet_client)), 291 base::Unretained(whispernet_client)),
247 base::Bind(&RpcHandler::AudioDirectiveListToWhispernetConnector, 292 base::Bind(&RpcHandler::AudioDirectiveListToWhispernetConnector,
248 base::Unretained(this))); 293 base::Unretained(this)));
249 294
250 whispernet_client->RegisterTokensCallback( 295 whispernet_client->RegisterTokensCallback(
251 base::Bind(&RpcHandler::ReportTokens, 296 base::Bind(&RpcHandler::ReportTokens,
252 // On destruction, this callback will be disconnected. 297 // On destruction, this callback will be disconnected.
253 base::Unretained(this))); 298 base::Unretained(this)));
254 } 299 }
255 300
256 // Private methods 301 // Private methods
257 302
258 void RpcHandler::RegisterResponseHandler( 303 void RpcHandler::RegisterResponseHandler(
259 const SuccessCallback& init_done_callback, 304 const SuccessCallback& init_done_callback,
305 const std::string& auth_token,
260 HttpPost* completed_post, 306 HttpPost* completed_post,
261 int http_status_code, 307 int http_status_code,
262 const std::string& response_data) { 308 const std::string& response_data) {
263 if (completed_post) { 309 if (completed_post) {
264 int elements_erased = pending_posts_.erase(completed_post); 310 int elements_erased = pending_posts_.erase(completed_post);
265 DCHECK(elements_erased); 311 DCHECK(elements_erased);
266 delete completed_post; 312 delete completed_post;
267 } 313 }
268 314
269 if (http_status_code != net::HTTP_OK) { 315 if (http_status_code != net::HTTP_OK) {
270 init_done_callback.Run(false); 316 init_done_callback.Run(false);
271 return; 317 return;
272 } 318 }
273 319
274 RegisterDeviceResponse response; 320 RegisterDeviceResponse response;
275 if (!response.ParseFromString(response_data)) { 321 if (!response.ParseFromString(response_data)) {
276 LOG(ERROR) << "Invalid RegisterDeviceResponse:\n" << response_data; 322 LOG(ERROR) << "Invalid RegisterDeviceResponse:\n" << response_data;
277 init_done_callback.Run(false); 323 init_done_callback.Run(false);
278 return; 324 return;
279 } 325 }
280 326
281 if (CopresenceErrorLogged(response.header().status())) 327 if (CopresenceErrorLogged(response.header().status())) {
328 init_done_callback.Run(false);
282 return; 329 return;
283 device_id_ = response.registered_device_id(); 330 }
284 DCHECK(!device_id_.empty()); 331
285 DVLOG(2) << "Device registration successful: id " << device_id_; 332 const std::string& device_id = response.registered_device_id();
333 DCHECK(!device_id.empty());
334 device_id_by_auth_token_[auth_token] = device_id;
335 DVLOG(2) << (auth_token.empty() ? "Anonymous" : "Authenticated")
336 << " device registration successful: id " << device_id;
286 init_done_callback.Run(true); 337 init_done_callback.Run(true);
287 } 338 }
288 339
289 void RpcHandler::ReportResponseHandler(const StatusCallback& status_callback, 340 void RpcHandler::ReportResponseHandler(const StatusCallback& status_callback,
290 HttpPost* completed_post, 341 HttpPost* completed_post,
291 int http_status_code, 342 int http_status_code,
292 const std::string& response_data) { 343 const std::string& response_data) {
293 if (completed_post) { 344 if (completed_post) {
294 int elements_erased = pending_posts_.erase(completed_post); 345 int elements_erased = pending_posts_.erase(completed_post);
295 DCHECK(elements_erased); 346 DCHECK(elements_erased);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 void RpcHandler::AddPlayingTokens(ReportRequest* request) { 435 void RpcHandler::AddPlayingTokens(ReportRequest* request) {
385 if (!directive_handler_) 436 if (!directive_handler_)
386 return; 437 return;
387 438
388 const std::string& audible_token = 439 const std::string& audible_token =
389 directive_handler_->GetCurrentAudioToken(AUDIBLE); 440 directive_handler_->GetCurrentAudioToken(AUDIBLE);
390 const std::string& inaudible_token = 441 const std::string& inaudible_token =
391 directive_handler_->GetCurrentAudioToken(INAUDIBLE); 442 directive_handler_->GetCurrentAudioToken(INAUDIBLE);
392 443
393 if (!audible_token.empty()) 444 if (!audible_token.empty())
394 AddTokenToRequest(request, AudioToken(audible_token, true)); 445 AddTokenToRequest(AudioToken(audible_token, true), request);
395 if (!inaudible_token.empty()) 446 if (!inaudible_token.empty())
396 AddTokenToRequest(request, AudioToken(inaudible_token, false)); 447 AddTokenToRequest(AudioToken(inaudible_token, false), request);
397 } 448 }
398 449
399 void RpcHandler::DispatchMessages( 450 void RpcHandler::DispatchMessages(
400 const RepeatedPtrField<SubscribedMessage>& messages) { 451 const RepeatedPtrField<SubscribedMessage>& messages) {
401 if (messages.size() == 0) 452 if (messages.size() == 0)
402 return; 453 return;
403 454
404 // Index the messages by subscription id. 455 // Index the messages by subscription id.
405 std::map<std::string, std::vector<Message>> messages_by_subscription; 456 std::map<std::string, std::vector<Message>> messages_by_subscription;
406 DVLOG(3) << "Dispatching " << messages.size() << " messages"; 457 DVLOG(3) << "Dispatching " << messages.size() << " messages";
407 for (const SubscribedMessage& message : messages) { 458 for (const SubscribedMessage& message : messages) {
408 for (const std::string& subscription_id : message.subscription_id()) { 459 for (const std::string& subscription_id : message.subscription_id()) {
409 messages_by_subscription[subscription_id].push_back( 460 messages_by_subscription[subscription_id].push_back(
410 message.published_message()); 461 message.published_message());
411 } 462 }
412 } 463 }
413 464
414 // Send the messages for each subscription. 465 // Send the messages for each subscription.
415 for (const auto& map_entry : messages_by_subscription) { 466 for (const auto& map_entry : messages_by_subscription) {
416 // TODO(ckehoe): Once we have the app ID from the server, we need to pass 467 // TODO(ckehoe): Once we have the app ID from the server, we need to pass
417 // it in here and get rid of the app id registry from the main API class. 468 // it in here and get rid of the app id registry from the main API class.
418 const std::string& subscription = map_entry.first; 469 const std::string& subscription = map_entry.first;
419 const std::vector<Message>& messages = map_entry.second; 470 const std::vector<Message>& messages = map_entry.second;
420 delegate_->HandleMessages("", subscription, messages); 471 delegate_->HandleMessages(std::string(), subscription, messages);
421 } 472 }
422 } 473 }
423 474
424 RequestHeader* RpcHandler::CreateRequestHeader( 475 RequestHeader* RpcHandler::CreateRequestHeader(
425 const std::string& client_name) const { 476 const std::string& client_name,
477 const std::string& device_id) const {
426 RequestHeader* header = new RequestHeader; 478 RequestHeader* header = new RequestHeader;
427 479
428 header->set_allocated_framework_version(CreateVersion( 480 header->set_allocated_framework_version(CreateVersion(
429 "Chrome", delegate_->GetPlatformVersionString())); 481 "Chrome", delegate_->GetPlatformVersionString()));
430 if (!client_name.empty()) { 482 if (!client_name.empty()) {
431 header->set_allocated_client_version( 483 header->set_allocated_client_version(
432 CreateVersion(client_name, std::string())); 484 CreateVersion(client_name, std::string()));
433 } 485 }
434 header->set_current_time_millis(base::Time::Now().ToJsTime()); 486 header->set_current_time_millis(base::Time::Now().ToJsTime());
435 header->set_registered_device_id(device_id_); 487 header->set_registered_device_id(device_id);
436 488
437 DeviceFingerprint* fingerprint = new DeviceFingerprint; 489 DeviceFingerprint* fingerprint = new DeviceFingerprint;
438 fingerprint->set_platform_version(delegate_->GetPlatformVersionString()); 490 fingerprint->set_platform_version(delegate_->GetPlatformVersionString());
439 fingerprint->set_type(CHROME_PLATFORM_TYPE); 491 fingerprint->set_type(CHROME_PLATFORM_TYPE);
440 header->set_allocated_device_fingerprint(fingerprint); 492 header->set_allocated_device_fingerprint(fingerprint);
441 493
442 return header; 494 return header;
443 } 495 }
444 496
445 template <class T> 497 template <class T>
446 void RpcHandler::SendServerRequest( 498 void RpcHandler::SendServerRequest(
447 const std::string& rpc_name, 499 const std::string& rpc_name,
500 const std::string& device_id,
448 const std::string& app_id, 501 const std::string& app_id,
502 const std::string& auth_token,
449 scoped_ptr<T> request, 503 scoped_ptr<T> request,
450 const PostCleanupCallback& response_handler) { 504 const PostCleanupCallback& response_handler) {
451 request->set_allocated_header(CreateRequestHeader(app_id)); 505 request->set_allocated_header(CreateRequestHeader(app_id, device_id));
452 server_post_callback_.Run(delegate_->GetRequestContext(), 506 server_post_callback_.Run(delegate_->GetRequestContext(),
453 rpc_name, 507 rpc_name,
508 delegate_->GetAPIKey(app_id),
509 auth_token,
454 make_scoped_ptr<MessageLite>(request.release()), 510 make_scoped_ptr<MessageLite>(request.release()),
455 response_handler); 511 response_handler);
456 } 512 }
457 513
458 void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter, 514 void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter,
459 const std::string& rpc_name, 515 const std::string& rpc_name,
516 const std::string& api_key,
517 const std::string& auth_token,
460 scoped_ptr<MessageLite> request_proto, 518 scoped_ptr<MessageLite> request_proto,
461 const PostCleanupCallback& callback) { 519 const PostCleanupCallback& callback) {
462 // Create the base URL to call. 520 // Create the base URL to call.
463 CommandLine* command_line = CommandLine::ForCurrentProcess(); 521 CommandLine* command_line = CommandLine::ForCurrentProcess();
464 const std::string copresence_server_host = 522 const std::string copresence_server_host =
465 command_line->HasSwitch(switches::kCopresenceServer) ? 523 command_line->HasSwitch(switches::kCopresenceServer) ?
466 command_line->GetSwitchValueASCII(switches::kCopresenceServer) : 524 command_line->GetSwitchValueASCII(switches::kCopresenceServer) :
467 kDefaultCopresenceServer; 525 kDefaultCopresenceServer;
468 526
469 // Create the request and keep a pointer until it completes. 527 // Create the request and keep a pointer until it completes.
470 HttpPost* http_post = new HttpPost( 528 HttpPost* http_post = new HttpPost(
471 url_context_getter, 529 url_context_getter,
472 copresence_server_host, 530 copresence_server_host,
473 rpc_name, 531 rpc_name,
532 api_key,
533 auth_token,
474 command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken), 534 command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken),
475 delegate_->GetAPIKey(),
476 *request_proto); 535 *request_proto);
477 536
478 http_post->Start(base::Bind(callback, http_post)); 537 http_post->Start(base::Bind(callback, http_post));
479 pending_posts_.insert(http_post); 538 pending_posts_.insert(http_post);
480 } 539 }
481 540
482 void RpcHandler::AudioDirectiveListToWhispernetConnector( 541 void RpcHandler::AudioDirectiveListToWhispernetConnector(
483 const std::string& token, 542 const std::string& token,
484 AudioType type, 543 AudioType type,
485 const WhispernetClient::SamplesCallback& samples_callback) { 544 const WhispernetClient::SamplesCallback& samples_callback) {
486 DCHECK(type == AUDIBLE || type == INAUDIBLE); 545 DCHECK(type == AUDIBLE || type == INAUDIBLE);
487 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient(); 546 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient();
488 if (whispernet_client) { 547 if (whispernet_client) {
489 whispernet_client->RegisterSamplesCallback(samples_callback); 548 whispernet_client->RegisterSamplesCallback(samples_callback);
490 whispernet_client->EncodeToken(token, type); 549 whispernet_client->EncodeToken(token, type);
491 } 550 }
492 } 551 }
493 552
494 } // namespace copresence 553 } // namespace copresence
OLDNEW
« no previous file with comments | « components/copresence/rpc/rpc_handler.h ('k') | components/copresence/rpc/rpc_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698