#ifndef CHROMECAST_NET_CONNECTIVITY_CHECKER_IMPL_H_
#define CHROMECAST_NET_CONNECTIVITY_CHECKER_IMPL_H_
#include <memory>
#include "base/cancelable_callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "chromecast/base/metrics/cast_metrics_helper.h"
#include "chromecast/net/connectivity_checker.h"
#include "chromecast/net/time_sync_tracker.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/network_connection_tracker.h"
class GURL;
namespace base {
class SingleThreadTaskRunner;
}
namespace net {
class HttpResponseHeaders;
}
namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}
namespace chromecast {
constexpr char kDefaultConnectivityCheckUrl[] =
"https://connectivitycheck.gstatic.com/generate_204";
constexpr char kHttpConnectivityCheckUrl[] =
"http://connectivitycheck.gstatic.com/generate_204";
constexpr net::HttpStatusCode kConnectivitySuccessStatusCode =
net::HTTP_NO_CONTENT;
constexpr base::TimeDelta kNetworkChangedDelay = base::Seconds(3);
class ConnectivityCheckerImpl
: public ConnectivityChecker,
public network::NetworkConnectionTracker::NetworkConnectionObserver,
public TimeSyncTracker::Observer {
public:
enum class ErrorType {
BAD_HTTP_STATUS = 1,
SSL_CERTIFICATE_ERROR = 2,
REQUEST_TIMEOUT = 3,
NET_ERROR = 4,
};
static scoped_refptr<ConnectivityCheckerImpl> Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_url_loader_factory,
network::NetworkConnectionTracker* network_connection_tracker,
TimeSyncTracker* time_sync_tracker);
static scoped_refptr<ConnectivityCheckerImpl> Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_url_loader_factory,
network::NetworkConnectionTracker* network_connection_tracker,
base::TimeDelta disconnected_probe_period,
base::TimeDelta connected_probe_period,
TimeSyncTracker* time_sync_tracker);
ConnectivityCheckerImpl(const ConnectivityCheckerImpl&) = delete;
ConnectivityCheckerImpl& operator=(const ConnectivityCheckerImpl&) = delete;
bool Connected() const override;
void Check() override;
void SetCastMetricsHelperForTesting(
metrics::CastMetricsHelper* cast_metrics_helper);
protected:
ConnectivityCheckerImpl(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
network::NetworkConnectionTracker* network_connection_tracker,
base::TimeDelta disconnected_probe_period,
base::TimeDelta connected_probe_period,
TimeSyncTracker* time_sync_tracker);
~ConnectivityCheckerImpl() override;
private:
void Initialize(std::unique_ptr<network::PendingSharedURLLoaderFactory>
pending_url_loader_factory);
void OnConnectionChanged(network::mojom::ConnectionType type) override;
void OnTimeSynced() override;
void OnConnectionChangedInternal();
void OnConnectivityCheckComplete(
scoped_refptr<net::HttpResponseHeaders> headers);
void Cancel();
void SetConnected(bool connected);
void OnUrlRequestError(ErrorType type);
void OnUrlRequestTimeout(base::TimeDelta timeout);
void CheckInternal();
std::unique_ptr<GURL> connectivity_check_url_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
const raw_ptr<TimeSyncTracker> time_sync_tracker_;
raw_ptr<metrics::CastMetricsHelper> cast_metrics_helper_;
mutable base::Lock connected_lock_;
bool connected_and_time_synced_;
bool network_connected_;
network::mojom::ConnectionType connection_type_;
unsigned int check_errors_;
bool network_changed_pending_;
base::CancelableOnceCallback<void()> timeout_;
base::CancelableOnceCallback<void()> delayed_check_;
const base::TimeDelta disconnected_probe_period_;
const base::TimeDelta connected_probe_period_;
bool first_connection_ = true;
base::WeakPtr<ConnectivityCheckerImpl> weak_this_;
base::WeakPtrFactory<ConnectivityCheckerImpl> weak_factory_;
};
}
#endif