Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: chromecast/net/connectivity_checker.cc

Issue 925183003: [Chromecast] Add connectivity checking for Chromecast. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromecast/net/connectivity_checker.cc
diff --git a/chromecast/net/connectivity_checker.cc b/chromecast/net/connectivity_checker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..633c2ac4013a37ffea8c818eabfff130772b82b8
--- /dev/null
+++ b/chromecast/net/connectivity_checker.cc
@@ -0,0 +1,175 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/net/connectivity_checker.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "chromecast/net/net_switches.h"
+#include "net/base/request_priority.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
+#include "net/http/http_status_code.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_fixed.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+
+namespace chromecast {
+
+namespace {
+
+// How often we perform connectivity checks in seconds
gunsch 2015/02/20 01:56:03 nit: avoid first-person references in comments, he
derekjchow1 2015/02/20 02:24:16 Done.
+const unsigned int kConnectivityPeriodSeconds = 1;
+
+// Number of consecutive bad responses we receive before we change connectivity
+// to offline
+const unsigned int kNumBadResponses = 3;
+
+// Default url for connectivity checking.
+const char kDefaultConnectivityCheckUrl[] =
+ "https://clients3.google.com/generate_204";
+
+} // namespace
+
+ConnectivityChecker::ConnectivityChecker(
+ const scoped_refptr<base::MessageLoopProxy>& loop_proxy)
+ : connectivity_observer_list_(
+ new ObserverListThreadSafe<ConnectivityObserver>()),
+ loop_proxy_(loop_proxy),
+ connected_(false),
+ bad_responses_(0) {
+ DCHECK(loop_proxy_.get());
+ loop_proxy->PostTask(FROM_HERE,
+ base::Bind(&ConnectivityChecker::Initialize, this));
+}
+
+void ConnectivityChecker::Initialize() {
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ base::CommandLine::StringType check_url_str =
+ command_line->GetSwitchValueNative(switches::kConnectivityCheckUrl);
+ connectivity_check_url_.reset(new GURL(
+ check_url_str.empty() ? kDefaultConnectivityCheckUrl : check_url_str));
+
+ net::URLRequestContextBuilder builder;
+ builder.set_proxy_config_service(
+ new net::ProxyConfigServiceFixed(net::ProxyConfig::CreateDirect()));
+ builder.DisableHttpCache();
+ url_request_context_.reset(builder.Build());
+
+ net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
+ if (!net::NetworkChangeNotifier::IsOffline()) {
+ loop_proxy_->PostTask(FROM_HERE,
+ base::Bind(&ConnectivityChecker::Check, this));
+ }
+}
+
+ConnectivityChecker::~ConnectivityChecker() {
+ DCHECK(loop_proxy_.get());
+ loop_proxy_->DeleteSoon(FROM_HERE, url_request_context_.release());
+}
+
+void ConnectivityChecker::AddConnectivityObserver(
+ ConnectivityObserver* observer) {
+ connectivity_observer_list_->AddObserver(observer);
+}
+
+void ConnectivityChecker::RemoveConnectivityObserver(
+ ConnectivityObserver* observer) {
+ connectivity_observer_list_->RemoveObserver(observer);
+}
+
+bool ConnectivityChecker::Connected() const {
+ return connected_;
+}
+
+void ConnectivityChecker::SetConnectivity(bool connected) {
+ if (connected)
+ bad_responses_ = 0;
gunsch 2015/02/20 01:57:28 how about moving "bad_responses_ = 0" to "OnRespon
derekjchow1 2015/02/20 02:24:16 Done.
+
+ if (connected_ == connected)
+ return;
+
+ connected_ = connected;
+ connectivity_observer_list_->Notify(
+ FROM_HERE, &ConnectivityObserver::OnConnectivityChanged, connected);
+ LOG(INFO) << "Global connection is: " << (connected ? "Up" : "Down");
+}
+
+void ConnectivityChecker::Check() {
+ if (!loop_proxy_->BelongsToCurrentThread()) {
+ loop_proxy_->PostTask(FROM_HERE,
+ base::Bind(&ConnectivityChecker::Check, this));
+ return;
+ }
+ DCHECK(url_request_context_.get());
+
+ // If url_request_ is non-null, there is already a check going on. Don't
+ // start another.
+ if (url_request_.get())
+ return;
+
+ VLOG(2) << "Connectivity check: url=" << *connectivity_check_url_;
+ url_request_ = url_request_context_->CreateRequest(
+ *connectivity_check_url_, net::MAXIMUM_PRIORITY, this, NULL);
+ url_request_->set_method("HEAD");
+ url_request_->Start();
+}
+
+void ConnectivityChecker::OnConnectionTypeChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ Cancel();
+
+ // If there is no connection, set connectivity to false. Otherwise retest
+ // connectivity
+ if (type == net::NetworkChangeNotifier::CONNECTION_NONE) {
+ SetConnectivity(false);
+ } else {
+ Check();
+ }
+}
+
+void ConnectivityChecker::OnResponseStarted(net::URLRequest* request) {
+ int http_response_code =
+ (request->status().is_success() &&
+ request->response_info().headers.get() != NULL)
+ ? request->response_info().headers->response_code()
+ : net::HTTP_BAD_REQUEST;
+
+ // Clears resources.
+ url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
+
+ if (http_response_code < 400) {
+ SetConnectivity(true);
+ return;
+ }
+
+ ++bad_responses_;
+ if (bad_responses_ > kNumBadResponses) {
+ bad_responses_ = kNumBadResponses;
+ SetConnectivity(false);
+ }
+
+ // Check again
+ if (!net::NetworkChangeNotifier::IsOffline()) {
+ loop_proxy_->PostDelayedTask(
+ FROM_HERE, base::Bind(&ConnectivityChecker::Check, this),
+ base::TimeDelta::FromSeconds(kConnectivityPeriodSeconds));
+ }
+}
+
+void ConnectivityChecker::OnReadCompleted(net::URLRequest* request,
+ int bytes_read) {
+ NOTREACHED();
+}
+
+void ConnectivityChecker::Cancel() {
+ if (url_request_.get()) {
+ VLOG(2) << "Cancel connectivity check in progress";
+ url_request_.reset(NULL); // URLRequest::Cancel() is called in destructor.
+ }
+}
+
+} // namespace chromecast

Powered by Google App Engine
This is Rietveld 408576698