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
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_PROXIMITY_AUTH_CONNECTION_H
6#define COMPONENTS_PROXIMITY_AUTH_CONNECTION_H
7
8#include "base/macros.h"
9#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/observer_list.h"
12#include "components/proximity_auth/remote_device.h"
13
14namespace proximity_auth {
15
16class ConnectionObserver;
17class WireMessage;
18
19// Base class representing a connection with a remote device, which is a
20// persistent bidirectional channel for sending and receiving wire messages.
21class Connection {
22 public:
23  enum Status {
24    DISCONNECTED,
25    IN_PROGRESS,
26    CONNECTED,
27  };
28
29  // Constructs a connection to the given |remote_device|.
30  explicit Connection(const RemoteDevice& remote_device);
31  virtual ~Connection();
32
33  // Returns true iff the connection's status is CONNECTED.
34  bool IsConnected() const;
35
36  // Sends a message to the remote device.
37  // |OnSendCompleted()| will be called for all observers upon completion with
38  // either success or failure.
39  void SendMessage(scoped_ptr<WireMessage> message);
40
41  void AddObserver(ConnectionObserver* observer);
42  void RemoveObserver(ConnectionObserver* observer);
43
44  const RemoteDevice& remote_device() const { return remote_device_; }
45
46  // Abstract methods that subclasses should implement:
47
48  // Attempts to connect to the remote device if not already connected.
49  virtual void Connect() = 0;
50
51  // Disconnects from the remote device.
52  virtual void Disconnect() = 0;
53
54 protected:
55  // Sets the connection's status to |status|. If this is different from the
56  // previous status, notifies observers of the change in status.
57  // Virtual for testing.
58  virtual void SetStatus(Status status);
59
60  Status status() const { return status_; }
61
62  // Called after attempting to send bytes over the connection, whether the
63  // message was successfully sent or not.
64  // Virtual for testing.
65  virtual void OnDidSendMessage(const WireMessage& message, bool success);
66
67  // Called when bytes are read from the connection. There should not be a send
68  // in progress when this function is called.
69  // Virtual for testing.
70  virtual void OnBytesReceived(const std::string& bytes);
71
72  // Sends bytes over the connection. The implementing class should call
73  // OnSendCompleted() once the send succeeds or fails. At most one send will be
74  // in progress.
75  virtual void SendMessageImpl(scoped_ptr<WireMessage> message) = 0;
76
77  // Deserializes the |recieved_bytes_| and returns the resulting WireMessage,
78  // or NULL if the message is malformed. Sets |is_incomplete_message| to true
79  // if the |serialized_message| does not have enough data to parse the header,
80  // or if the message length encoded in the message header exceeds the size of
81  // the |serialized_message|. Exposed for testing.
82  virtual scoped_ptr<WireMessage> DeserializeWireMessage(
83      bool* is_incomplete_message);
84
85 private:
86  // The remote device corresponding to this connection.
87  const RemoteDevice remote_device_;
88
89  // The current status of the connection.
90  Status status_;
91
92  // The registered observers of the connection.
93  ObserverList<ConnectionObserver> observers_;
94
95  // A temporary buffer storing bytes received before a received message can be
96  // fully constructed.
97  std::string received_bytes_;
98
99  // Whether a message is currently in the process of being sent.
100  bool is_sending_message_;
101
102  DISALLOW_COPY_AND_ASSIGN(Connection);
103};
104
105}  // namespace proximity_auth
106
107#endif  // COMPONENTS_PROXIMITY_AUTH_CONNECTION_H
108