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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// Copyright 2017 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_COMPONENTS_TETHER_CONNECT_TETHERING_OPERATION_H_
#define CHROMEOS_ASH_COMPONENTS_TETHER_CONNECT_TETHERING_OPERATION_H_
#include <stdint.h>
#include <map>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "chromeos/ash/components/tether/message_transfer_operation.h"
namespace ash::tether {
class MessageWrapper;
// Operation used to request that a tether host share its Internet connection.
// Attempts a connection to the RemoteDevice passed to its constructor and
// notifies observers when the RemoteDevice sends a response.
class ConnectTetheringOperation : public MessageTransferOperation {
public:
// Includes all error codes of ConnectTetheringResponse_ResponseCode, but
// includes extra values: |INVALID_HOTSPOT_CREDENTIALS|,
// |UNRECOGNIZED_RESPONSE_ERROR|.
enum HostResponseErrorCode {
PROVISIONING_FAILED = 0,
TETHERING_TIMEOUT = 1,
TETHERING_UNSUPPORTED = 2,
NO_CELL_DATA = 3,
ENABLING_HOTSPOT_FAILED = 4,
ENABLING_HOTSPOT_TIMEOUT = 5,
UNKNOWN_ERROR = 6,
NO_RESPONSE = 7,
INVALID_HOTSPOT_CREDENTIALS = 8,
UNRECOGNIZED_RESPONSE_ERROR = 9,
INVALID_ACTIVE_EXISTING_SOFT_AP_CONFIG = 10,
INVALID_NEW_SOFT_AP_CONFIG = 11,
INVALID_WIFI_AP_CONFIG = 12,
};
class Factory {
public:
static std::unique_ptr<ConnectTetheringOperation> Create(
const TetherHost& tether_host,
raw_ptr<HostConnection::Factory> host_connection_factory,
bool setup_required);
static void SetFactoryForTesting(Factory* factory);
protected:
virtual ~Factory();
virtual std::unique_ptr<ConnectTetheringOperation> CreateInstance(
const TetherHost& tether_host,
raw_ptr<HostConnection::Factory> host_connection_factory,
bool setup_required) = 0;
private:
static Factory* factory_instance_;
};
class Observer {
public:
virtual void OnConnectTetheringRequestSent() = 0;
virtual void OnSuccessfulConnectTetheringResponse(
const std::string& ssid,
const std::string& password) = 0;
virtual void OnConnectTetheringFailure(
HostResponseErrorCode error_code) = 0;
};
ConnectTetheringOperation(const ConnectTetheringOperation&) = delete;
ConnectTetheringOperation& operator=(const ConnectTetheringOperation&) =
delete;
~ConnectTetheringOperation() override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
protected:
ConnectTetheringOperation(
const TetherHost& tether_host,
raw_ptr<HostConnection::Factory> host_connection_factory,
bool setup_required);
// MessageTransferOperation:
void OnDeviceAuthenticated() override;
void OnMessageReceived(
std::unique_ptr<MessageWrapper> message_wrapper) override;
void OnOperationFinished() override;
MessageType GetMessageTypeForConnection() override;
uint32_t GetMessageTimeoutSeconds() override;
void NotifyConnectTetheringRequestSent();
void NotifyObserversOfSuccessfulResponse(const std::string& ssid,
const std::string& password);
void NotifyObserversOfConnectionFailure(HostResponseErrorCode error_code);
private:
friend class ConnectTetheringOperationTest;
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
SuccessWithValidResponse);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
SuccessButInvalidResponse);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest, UnknownError);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest, ProvisioningFailed);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
InvalidActiveExistingSoftApConfig);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
InvalidNewSoftApConfig);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest, InvalidWifiApConfig);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
NotifyConnectTetheringRequest);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
GetMessageTimeoutSeconds);
FRIEND_TEST_ALL_PREFIXES(ConnectTetheringOperationTest,
MessageSentOnceAuthenticated);
HostResponseErrorCode ConnectTetheringResponseCodeToHostResponseErrorCode(
ConnectTetheringResponse_ResponseCode error_code);
void SetClockForTest(base::Clock* clock_for_test);
// The amount of time this operation will wait for a response. The timeout
// values are different depending on whether setup is needed on the host.
static const uint32_t kSetupNotRequiredResponseTimeoutSeconds;
static const uint32_t kSetupRequiredResponseTimeoutSeconds;
raw_ptr<base::Clock> clock_;
bool setup_required_;
// These values are saved in OnMessageReceived() and returned in
// OnOperationFinished().
std::string ssid_to_return_;
std::string password_to_return_;
HostResponseErrorCode error_code_to_return_;
base::Time connect_tethering_request_start_time_;
base::ObserverList<Observer>::Unchecked observer_list_;
base::WeakPtrFactory<ConnectTetheringOperation> weak_ptr_factory_{this};
};
} // namespace ash::tether
#endif // CHROMEOS_ASH_COMPONENTS_TETHER_CONNECT_TETHERING_OPERATION_H_
|