#ifndef CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_CONNECTION_HANDLER_H_
#define CHROMEOS_ASH_COMPONENTS_NETWORK_CELLULAR_CONNECTION_HANDLER_H_
#include <memory>
#include <optional>
#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "chromeos/ash/components/dbus/hermes/hermes_response_status.h"
#include "chromeos/ash/components/network/cellular_inhibitor.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"
#include "dbus/object_path.h"
namespace ash {
namespace cellular_setup {
class ESimTestBase;
}
class CellularESimProfileHandler;
class CellularInhibitor;
class NetworkState;
class COMPONENT_EXPORT(CHROMEOS_NETWORK) CellularConnectionHandler
: public NetworkStateHandlerObserver {
public:
enum class PrepareCellularConnectionResult {
kSuccess = 0,
kCouldNotFindNetworkWithIccid = 1,
kInhibitFailed = 2,
kCouldNotFindRelevantEuicc = 3,
kRefreshProfilesFailed = 4,
kCouldNotFindRelevantESimProfile = 5,
kEnableProfileFailed = 6,
kTimeoutWaitingForConnectable = 7,
kSimLocked = 8,
kMaxValue = kSimLocked
};
CellularConnectionHandler();
CellularConnectionHandler(const CellularConnectionHandler&) = delete;
CellularConnectionHandler& operator=(const CellularConnectionHandler&) =
delete;
~CellularConnectionHandler() override;
void Init(NetworkStateHandler* network_state_handler,
CellularInhibitor* cellular_inhibitor,
CellularESimProfileHandler* cellular_esim_profile_handler);
typedef base::OnceCallback<void(const std::string&, bool)> SuccessCallback;
typedef base::OnceCallback<void(const std::string&, const std::string&)>
ErrorCallback;
void PrepareExistingCellularNetworkForConnection(
const std::string& iccid,
SuccessCallback success_callback,
ErrorCallback error_callback);
void PrepareNewlyInstalledCellularNetworkForConnection(
const dbus::ObjectPath& euicc_path,
const dbus::ObjectPath& profile_path,
std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock,
SuccessCallback success_callback,
ErrorCallback error_callback);
private:
friend class CellularESimInstallerTest;
friend class CellularPolicyHandlerTest;
friend class ManagedNetworkConfigurationHandlerTest;
friend class cellular_setup::ESimTestBase;
struct ConnectionRequestMetadata {
ConnectionRequestMetadata(const std::string& iccid,
SuccessCallback success_callback,
ErrorCallback error_callback);
ConnectionRequestMetadata(
const dbus::ObjectPath& euicc_path,
const dbus::ObjectPath& profile_path,
std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock,
SuccessCallback success_callback,
ErrorCallback error_callback);
~ConnectionRequestMetadata();
std::optional<std::string> iccid;
std::optional<dbus::ObjectPath> euicc_path;
std::optional<dbus::ObjectPath> profile_path;
std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock;
bool did_connection_require_enabling_profile = false;
SuccessCallback success_callback;
ErrorCallback error_callback;
};
enum class ConnectionState {
kIdle,
kCheckingServiceStatus,
kInhibitingScans,
kRequestingProfilesBeforeEnabling,
kEnablingProfile,
kWaitingForConnectable,
kWaitingForShillAutoConnect,
};
friend std::ostream& operator<<(std::ostream& stream,
const ConnectionState& step);
static const base::TimeDelta kWaitingForAutoConnectTimeout;
static std::optional<std::string> ResultToErrorString(
PrepareCellularConnectionResult result);
void NetworkListChanged() override;
void NetworkPropertiesUpdated(const NetworkState* network) override;
void NetworkIdentifierTransitioned(const std::string& old_service_path,
const std::string& new_service_path,
const std::string& old_guid,
const std::string& new_guid) override;
void NetworkConnectionStateChanged(const NetworkState* network) override;
void DevicePropertiesUpdated(const DeviceState* device) override;
void ProcessRequestQueue();
void TransitionToConnectionState(ConnectionState state);
void CompleteConnectionAttempt(PrepareCellularConnectionResult result,
bool auto_connected);
const NetworkState* GetNetworkStateForCurrentOperation() const;
std::optional<dbus::ObjectPath> GetEuiccPathForCurrentOperation() const;
std::optional<dbus::ObjectPath> GetProfilePathForCurrentOperation() const;
void CheckServiceStatus();
void OnInhibitScanResult(
std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock);
void RequestInstalledProfiles();
void OnRefreshProfileListResult(
std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock);
void EnableProfile();
void OnEnableCarrierProfileResult(HermesResponseStatus status);
void UninhibitScans(const std::optional<std::string>& error_before_uninhibit);
void OnUninhibitScanResult(
const std::optional<std::string>& error_before_uninhibit,
bool success);
void HandleNetworkPropertiesUpdate();
void CheckForConnectable();
void OnWaitForConnectableTimeout();
void StartWaitingForShillAutoConnect();
void CheckForAutoConnected();
void OnWaitForAutoConnectTimeout();
base::OneShotTimer timer_;
raw_ptr<NetworkStateHandler> network_state_handler_ = nullptr;
base::ScopedObservation<NetworkStateHandler, NetworkStateHandlerObserver>
network_state_handler_observer_{this};
raw_ptr<CellularInhibitor> cellular_inhibitor_ = nullptr;
raw_ptr<CellularESimProfileHandler, DanglingUntriaged>
cellular_esim_profile_handler_ = nullptr;
ConnectionState state_ = ConnectionState::kIdle;
base::queue<std::unique_ptr<ConnectionRequestMetadata>> request_queue_;
base::WeakPtrFactory<CellularConnectionHandler> weak_ptr_factory_{this};
};
}
#endif