Chromium Code Reviews| Index: components/proximity_auth/connection.cc |
| diff --git a/components/proximity_auth/connection.cc b/components/proximity_auth/connection.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2f87378c6c551fab9d15c7ed9e3f2a0ad235c849 |
| --- /dev/null |
| +++ b/components/proximity_auth/connection.cc |
| @@ -0,0 +1,123 @@ |
| +// 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/proximity_auth/connection.h" |
| + |
| +#include "base/logging.h" |
| +#include "components/proximity_auth/connection_observer.h" |
| +#include "components/proximity_auth/permit_message.h" |
| + |
| +namespace proximity_auth { |
| +namespace { |
| + |
| +// Most EasyUnlock messages fit easily into 128 bytes. |
| +const int kInitialBufferCapacity = 128; |
| + |
| +} // namespace |
| + |
| +Connection::Connection(const RemoteDevice& remote_device) |
| + : remote_device_(remote_device), |
| + status_(DISCONNECTED), |
| + is_sending_message_(false) { |
| +} |
| + |
| +Connection::~Connection() { |
| +} |
| + |
| +bool Connection::IsConnected() const { |
| + return status_ == CONNECTED; |
| +} |
| + |
| +void Connection::SendMessage(scoped_ptr<PermitMessage> message) { |
| + if (!IsConnected()) { |
| + VLOG(1) << "Cannot send message when disconnected."; |
| + return; |
| + } |
| + |
| + if (is_sending_message_) { |
| + VLOG(1) << "Another message is currently in progress."; |
| + return; |
| + } |
| + |
| + is_sending_message_ = true; |
| + SendMessageImpl(message.Pass()); |
| +} |
| + |
| +void Connection::AddObserver(ConnectionObserver* observer) { |
| + observers_.AddObserver(observer); |
| +} |
| + |
| +void Connection::RemoveObserver(ConnectionObserver* observer) { |
| + observers_.RemoveObserver(observer); |
| +} |
| + |
| +void Connection::SetStatus(Status status) { |
| + if (status_ == status) |
| + return; |
| + |
| + received_bytes_ = NULL; |
| + |
| + Status old_status = status_; |
| + status_ = status; |
| + FOR_EACH_OBSERVER(ConnectionObserver, observers_, |
| + OnConnectionStatusChanged(*this, old_status, status_)); |
| +} |
| + |
| +void Connection::OnDidSendMessage(const PermitMessage& message, |
| + bool success) { |
| + if (!is_sending_message_) { |
| + VLOG(1) << "Send completed, but no message in progress."; |
| + return; |
| + } |
| + |
| + FOR_EACH_OBSERVER( |
| + ConnectionObserver, observers_, OnSendCompleted(*this, message, success)); |
| + is_sending_message_ = false; |
|
Tim Song
2014/09/05 00:30:33
move this line up in case an observer wants to sen
Ilya Sherman
2014/09/05 01:02:11
Done, though that seems a little fragile, since ob
Tim Song
2014/09/05 03:10:33
Alternative, expose a is_sending_message() functio
|
| +} |
| + |
| +void Connection::OnBytesReceived(scoped_refptr<net::IOBuffer> io_buffer, |
| + int bytes_received) { |
| + if (!IsConnected()) { |
| + VLOG(1) << "Received bytes, but not connected."; |
| + return; |
| + } |
| + |
| + // Allocate an initial buffer if one does not already exist. |
| + if (!received_bytes_) { |
| + received_bytes_ = new net::GrowableIOBuffer; |
| + received_bytes_->SetCapacity(kInitialBufferCapacity); |
| + } |
| + |
| + // Grow the buffer if necessary. |
| + if (received_bytes_->RemainingCapacity() < bytes_received) |
| + received_bytes_->SetCapacity(received_bytes_->capacity() + bytes_received); |
| + |
| + // TODO(tengs): Clear buffer after a timeout as a guard. |
|
Tim Song
2014/09/05 00:30:33
We can remove this TODO. If the phone sends garbag
Ilya Sherman
2014/09/05 01:02:11
Done.
|
| + memcpy(received_bytes_->data(), io_buffer->data(), bytes_received); |
| + received_bytes_->set_offset(received_bytes_->offset() + bytes_received); |
| + |
| + if (HasReceivedCompleteMessage()) { |
| + scoped_ptr<PermitMessage> message = DeserializePermitMessage(); |
| + if (message) { |
| + FOR_EACH_OBSERVER(ConnectionObserver, observers_, |
| + OnMessageReceived(*this, *message)); |
| + } |
| + |
| + // Whether the message was parsed successfully or not, clear the |
| + // |received_bytes_| buffer. |
| + received_bytes_ = NULL; |
| + } |
| +} |
| + |
| +bool Connection::HasReceivedCompleteMessage() { |
| + return PermitMessage::IsCompleteMessage( |
| + received_bytes_->StartOfBuffer(), received_bytes_->offset()); |
| +} |
| + |
| +scoped_ptr<PermitMessage> Connection::DeserializePermitMessage() { |
| + return PermitMessage::FromBytes( |
| + received_bytes_->StartOfBuffer(), received_bytes_->offset()); |
| +} |
| + |
| +} // namespace proximity_auth |