chromium/chromeos/ash/services/secure_channel/authenticated_channel.h

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_
#define CHROMEOS_ASH_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_

#include <optional>
#include <string>

#include "base/functional/callback_forward.h"
#include "base/observer_list.h"
#include "chromeos/ash/services/secure_channel/file_transfer_update_callback.h"
#include "chromeos/ash/services/secure_channel/public/mojom/nearby_connector.mojom-shared.h"
#include "chromeos/ash/services/secure_channel/public/mojom/secure_channel.mojom.h"
#include "chromeos/ash/services/secure_channel/public/mojom/secure_channel_types.mojom.h"

namespace ash::secure_channel {

// A full-duplex communication channel which is guaranteed to be authenticated
// (i.e., the two sides of the channel both belong to the same underlying user).
// All messages sent and received over the channel are encrypted.
class AuthenticatedChannel {
 public:
  class Observer {
   public:
    virtual ~Observer();
    virtual void OnDisconnected() = 0;
    virtual void OnMessageReceived(const std::string& feature,
                                   const std::string& payload) = 0;
    virtual void OnNearbyConnectionStateChanged(
        mojom::NearbyConnectionStep step,
        mojom::NearbyConnectionStepResult result) = 0;
  };

  AuthenticatedChannel(const AuthenticatedChannel&) = delete;
  AuthenticatedChannel& operator=(const AuthenticatedChannel&) = delete;

  virtual ~AuthenticatedChannel();

  virtual void GetConnectionMetadata(
      base::OnceCallback<void(mojom::ConnectionMetadataPtr)> callback) = 0;

  // Sends a message with the specified |feature| and |payload|. Once the
  // message has been sent, |on_sent_callback| will be invoked. Returns whether
  // this AuthenticatedChannel was able to start sending the message; this
  // function only fails if the underlying connection has been disconnected.
  bool SendMessage(const std::string& feature,
                   const std::string& payload,
                   base::OnceClosure on_sent_callback);

  // Registers |payload_files| to receive an incoming file transfer with
  // the given |payload_id|. |registration_result_callback| will return true
  // if the file was successfully registered, or false if the registration
  // failed or if this operation is not supported by the connection type.
  // Callers can listen to progress information about the transfer through the
  // |file_transfer_update_callback| if the registration was successful.
  void RegisterPayloadFile(
      int64_t payload_id,
      mojom::PayloadFilesPtr payload_files,
      FileTransferUpdateCallback file_transfer_update_callback,
      base::OnceCallback<void(bool)> registration_result_callback);

  // Disconnects this channel. Note that disconnection is an asynchronous
  // operation; observers will be notified when disconnection completes via the
  // OnDisconnected() callback.
  void Disconnect();

  bool is_disconnected() const { return is_disconnected_; }

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

 protected:
  AuthenticatedChannel();

  // Performs the actual logic of sending the message. By the time this function
  // is called, it has already been confirmed that the channel has not been
  // disconnected.
  virtual void PerformSendMessage(const std::string& feature,
                                  const std::string& payload,
                                  base::OnceClosure on_sent_callback) = 0;

  // Performs the actual logic of registering payload files. By the time this
  // function is called, it has already been confirmed that the channel has not
  // been disconnected.
  virtual void PerformRegisterPayloadFile(
      int64_t payload_id,
      mojom::PayloadFilesPtr payload_files,
      FileTransferUpdateCallback file_transfer_update_callback,
      base::OnceCallback<void(bool)> registration_result_callback) = 0;

  // Performs the actual logic of disconnecting. By the time this function is
  // called, it has already been confirmed that the channel is still indeed
  // connected.
  virtual void PerformDisconnection() = 0;

  void NotifyDisconnected();
  void NotifyMessageReceived(const std::string& feature,
                             const std::string& payload);
  void NotifyNearbyConnectionStateChanged(
      mojom::NearbyConnectionStep step,
      mojom::NearbyConnectionStepResult result);

 private:
  base::ObserverList<Observer>::Unchecked observer_list_;
  bool is_disconnected_ = false;
};

}  // namespace ash::secure_channel

#endif  // CHROMEOS_ASH_SERVICES_SECURE_CHANNEL_AUTHENTICATED_CHANNEL_H_