summaryrefslogtreecommitdiffstats
path: root/components/copresence/copresence_client.cc
blob: 60e45e15d2156368eddf0e575f1812e6339e9dc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/copresence/public/copresence_client.h"

#include "base/bind.h"
#include "components/copresence/public/copresence_client_delegate.h"
#include "components/copresence/public/whispernet_client.h"
#include "components/copresence/rpc/rpc_handler.h"

namespace copresence {

PendingRequest::PendingRequest(const copresence::ReportRequest& report,
                               const std::string app_id,
                               const StatusCallback& callback)
    : report(report), app_id(app_id), callback(callback) {
}

PendingRequest::~PendingRequest() {
}

// Public methods

CopresenceClient::CopresenceClient(CopresenceClientDelegate* delegate)
    : delegate_(delegate), init_failed_(false), pending_init_operations_(0) {
  DVLOG(3) << "Initializing client.";
  pending_init_operations_++;
  rpc_handler_.reset(
      new RpcHandler(delegate,
                     base::Bind(&CopresenceClient::InitStepComplete,
                                AsWeakPtr(),
                                "Copresence device registration")));

  pending_init_operations_++;
  delegate_->GetWhispernetClient()->Initialize(
      base::Bind(&CopresenceClient::InitStepComplete,
                 AsWeakPtr(),
                 "Whispernet proxy initialization"));
}

CopresenceClient::~CopresenceClient() {
}

void CopresenceClient::Shutdown() {
  DVLOG(3) << "Shutting down client.";
  delegate_->GetWhispernetClient()->Shutdown();
  rpc_handler_->DisconnectFromWhispernet();
}

// Returns false if any operations were malformed.
void CopresenceClient::ExecuteReportRequest(copresence::ReportRequest request,
                                            const std::string& app_id,
                                            const StatusCallback& callback) {
  // Don't take on any more requests, we can't execute any, init failed.
  if (init_failed_) {
    callback.Run(FAIL);
    return;
  }

  if (pending_init_operations_) {
    pending_requests_queue_.push_back(
        PendingRequest(request, app_id, callback));
  } else {
    rpc_handler_->SendReportRequest(
        make_scoped_ptr(new copresence::ReportRequest(request)),
        app_id,
        callback);
  }
}

// Private methods

void CopresenceClient::CompleteInitialization() {
  if (pending_init_operations_)
    return;

  if (!init_failed_)
    rpc_handler_->ConnectToWhispernet(delegate_->GetWhispernetClient());

  for (std::vector<PendingRequest>::iterator request =
           pending_requests_queue_.begin();
       request != pending_requests_queue_.end();
       ++request) {
    if (init_failed_) {
      request->callback.Run(FAIL);
    } else {
      rpc_handler_->SendReportRequest(
          make_scoped_ptr(new copresence::ReportRequest(request->report)),
          request->app_id,
          request->callback);
    }
  }
  pending_requests_queue_.clear();
}

void CopresenceClient::InitStepComplete(const std::string& step, bool success) {
  if (!success) {
    LOG(ERROR) << step << " failed!";
    init_failed_ = true;
  }

  DVLOG(3) << "Init step: " << step << " complete.";
  pending_init_operations_--;
  CompleteInitialization();
}

}  // namespace copresence