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

Unified Diff: chrome/browser/android/feedback/connectivity_checker.cc

Issue 1127983002: Add connectivity check for Android feedback. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments Created 5 years, 7 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: chrome/browser/android/feedback/connectivity_checker.cc
diff --git a/chrome/browser/android/feedback/connectivity_checker.cc b/chrome/browser/android/feedback/connectivity_checker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6a3b177a726bbd42e13e884b5fe9a50e39a64ec2
--- /dev/null
+++ b/chrome/browser/android/feedback/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 "chrome/browser/android/feedback/connectivity_checker.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_android.h"
+#include "jni/ConnectivityChecker_jni.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+#include "url/gurl.h"
+
+namespace chrome {
+namespace android {
+
+namespace {
+
+void ExecuteCallback(jobject callback, bool connected) {
+ Java_ConnectivityChecker_executeCallback(base::android::AttachCurrentThread(),
+ callback, connected);
+}
+
+void ExecuteCallbackFromRef(
+ base::android::ScopedJavaGlobalRef<jobject>* callback,
+ bool connected) {
+ ExecuteCallback(callback->obj(), connected);
+}
+
+void PostCallback(JNIEnv* env, jobject j_callback, bool connected) {
+ base::android::ScopedJavaGlobalRef<jobject>* callback =
+ new base::android::ScopedJavaGlobalRef<jobject>();
+ callback->Reset(env, j_callback);
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ExecuteCallbackFromRef, base::Owned(callback), connected));
+}
+
+// A utility class for checking if the device is currently connected to the
+// Internet.
+class ConnectivityChecker : public net::URLFetcherDelegate {
+ public:
+ ConnectivityChecker(Profile* profile,
+ const GURL& url,
+ const base::TimeDelta& timeout,
+ const base::android::JavaRef<jobject>& java_callback);
+
+ // Kicks off the asynchronous connectivity check. When the request has
+ // completed, |this| is deleted.
+ void StartAsyncCheck();
+
+ // net::URLFetcherDelegate implementation:
+ void OnURLFetchComplete(const net::URLFetcher* source) override;
+
+ // Cancels the URLFetcher, and triggers the callback with a negative result.
+ void Cancel();
+
+ private:
+ // The context in which the connectivity check is performed.
+ net::URLRequestContextGetter* request_context_;
+
+ // The URL to connect to.
+ const GURL& url_;
+
+ // How long to wait for a response before giving up.
+ const base::TimeDelta& timeout_;
+
+ // Holds the Java object which will get the callback with the result.
+ base::android::ScopedJavaGlobalRef<jobject> java_callback_;
+
+ // The URLFetcher that executes the connectivity check.
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+
+ // Whether |this| is already being destroyed, at which point the callback
+ // has already happened, and no further action should be taken.
+ bool is_being_destroyed_;
+
+ scoped_ptr<base::OneShotTimer<ConnectivityChecker>> expiration_timer_;
+};
+
+void ConnectivityChecker::OnURLFetchComplete(const net::URLFetcher* source) {
+ DCHECK_EQ(url_fetcher_.get(), source);
cjhopman 2015/05/08 18:58:39 i'd put this after the early return stuff
nyquist 2015/05/12 00:42:30 Done.
+ if (is_being_destroyed_)
+ return;
+ is_being_destroyed_ = true;
+
+ net::URLRequestStatus status = source->GetStatus();
+ int response_code = source->GetResponseCode();
+
+ bool connected = status.is_success() && response_code == net::HTTP_NO_CONTENT;
+ ExecuteCallback(java_callback_.obj(), connected);
+
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+}
+
+ConnectivityChecker::ConnectivityChecker(
+ Profile* profile,
+ const GURL& url,
+ const base::TimeDelta& timeout,
+ const base::android::JavaRef<jobject>& java_callback)
+ : request_context_(profile->GetRequestContext()),
+ url_(url),
+ timeout_(timeout),
+ java_callback_(java_callback),
+ is_being_destroyed_(false) {
+}
+
+void ConnectivityChecker::StartAsyncCheck() {
+ url_fetcher_ =
+ net::URLFetcher::Create(url_, net::URLFetcher::GET, this).Pass();
+ url_fetcher_->SetRequestContext(request_context_);
+ url_fetcher_->SetStopOnRedirect(true);
+ url_fetcher_->SetAutomaticallyRetryOn5xx(false);
+ url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
+ url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SEND_AUTH_DATA);
+ url_fetcher_->Start();
+ expiration_timer_.reset(new base::OneShotTimer<ConnectivityChecker>());
+ expiration_timer_->Start(FROM_HERE, timeout_, this,
+ &ConnectivityChecker::Cancel);
+}
+
+void ConnectivityChecker::Cancel() {
+ if (is_being_destroyed_)
+ return;
+ is_being_destroyed_ = true;
+ url_fetcher_.reset();
+ ExecuteCallback(java_callback_.obj(), false);
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+}
+
+} // namespace
+
+void CheckConnectivity(JNIEnv* env,
+ jclass clazz,
+ jobject j_profile,
+ jstring j_url,
+ jlong j_timeout_ms,
+ jobject j_callback) {
+ Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
+ if (!profile) {
+ PostCallback(env, j_callback, false);
+ return;
+ }
+ GURL url(base::android::ConvertJavaStringToUTF8(env, j_url));
+ if (!url.is_valid()) {
+ PostCallback(env, j_callback, false);
+ return;
+ }
+
+ // This object will be deleted when the connectivity check has completed.
+ ConnectivityChecker* connectivity_checker = new ConnectivityChecker(
+ profile, url, base::TimeDelta::FromMilliseconds(j_timeout_ms),
+ base::android::ScopedJavaLocalRef<jobject>(env, j_callback));
+ connectivity_checker->StartAsyncCheck();
+}
+
+bool RegisterConnectivityChecker(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698