Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / android / feedback / connectivity_checker.cc
blobfa2e133090367a59beb7957a351d21daff670046
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/android/feedback/connectivity_checker.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/time/time.h"
12 #include "base/timer/timer.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_android.h"
15 #include "jni/ConnectivityChecker_jni.h"
16 #include "net/base/load_flags.h"
17 #include "net/http/http_status_code.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_fetcher_delegate.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "net/url_request/url_request_status.h"
22 #include "url/gurl.h"
24 namespace chrome {
25 namespace android {
27 namespace {
28 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.feedback
29 // GENERATED_JAVA_PREFIX_TO_STRIP: CONNECTIVITY_CHECK_RESULT_
30 enum ConnectivityCheckResult {
31 CONNECTIVITY_CHECK_RESULT_UNKNOWN = 0,
32 CONNECTIVITY_CHECK_RESULT_CONNECTED = 1,
33 CONNECTIVITY_CHECK_RESULT_NOT_CONNECTED = 2,
34 CONNECTIVITY_CHECK_RESULT_TIMEOUT = 3,
35 CONNECTIVITY_CHECK_RESULT_ERROR = 4,
36 CONNECTIVITY_CHECK_RESULT_END = 5
39 void ExecuteCallback(jobject callback, ConnectivityCheckResult result) {
40 CHECK(result >= CONNECTIVITY_CHECK_RESULT_UNKNOWN);
41 CHECK(result < CONNECTIVITY_CHECK_RESULT_END);
42 Java_ConnectivityChecker_executeCallback(base::android::AttachCurrentThread(),
43 callback, result);
46 void ExecuteCallbackFromRef(
47 base::android::ScopedJavaGlobalRef<jobject>* callback,
48 ConnectivityCheckResult result) {
49 ExecuteCallback(callback->obj(), result);
52 void PostCallback(JNIEnv* env,
53 jobject j_callback,
54 ConnectivityCheckResult result) {
55 base::MessageLoop::current()->PostTask(
56 FROM_HERE,
57 base::Bind(&ExecuteCallbackFromRef,
58 base::Owned(new base::android::ScopedJavaGlobalRef<jobject>(
59 env, j_callback)),
60 result));
63 // A utility class for checking if the device is currently connected to the
64 // Internet.
65 class ConnectivityChecker : public net::URLFetcherDelegate {
66 public:
67 ConnectivityChecker(Profile* profile,
68 const GURL& url,
69 const base::TimeDelta& timeout,
70 const base::android::JavaRef<jobject>& java_callback);
72 // Kicks off the asynchronous connectivity check. When the request has
73 // completed, |this| is deleted.
74 void StartAsyncCheck();
76 // net::URLFetcherDelegate implementation:
77 void OnURLFetchComplete(const net::URLFetcher* source) override;
79 // Cancels the URLFetcher, and triggers the callback with a negative result
80 // and the timeout flag set.
81 void OnTimeout();
83 private:
84 // The context in which the connectivity check is performed.
85 net::URLRequestContextGetter* request_context_;
87 // The URL to connect to.
88 const GURL& url_;
90 // How long to wait for a response before giving up.
91 const base::TimeDelta timeout_;
93 // Holds the Java object which will get the callback with the result.
94 base::android::ScopedJavaGlobalRef<jobject> java_callback_;
96 // The URLFetcher that executes the connectivity check.
97 scoped_ptr<net::URLFetcher> url_fetcher_;
99 // Whether |this| is already being destroyed, at which point the callback
100 // has already happened, and no further action should be taken.
101 bool is_being_destroyed_;
103 scoped_ptr<base::OneShotTimer<ConnectivityChecker>> expiration_timer_;
106 void ConnectivityChecker::OnURLFetchComplete(const net::URLFetcher* source) {
107 if (is_being_destroyed_)
108 return;
109 is_being_destroyed_ = true;
111 DCHECK_EQ(url_fetcher_.get(), source);
112 net::URLRequestStatus status = source->GetStatus();
113 int response_code = source->GetResponseCode();
115 bool connected = status.is_success() && response_code == net::HTTP_NO_CONTENT;
116 if (connected) {
117 ExecuteCallback(java_callback_.obj(), CONNECTIVITY_CHECK_RESULT_CONNECTED);
118 } else {
119 ExecuteCallback(java_callback_.obj(),
120 CONNECTIVITY_CHECK_RESULT_NOT_CONNECTED);
123 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
126 ConnectivityChecker::ConnectivityChecker(
127 Profile* profile,
128 const GURL& url,
129 const base::TimeDelta& timeout,
130 const base::android::JavaRef<jobject>& java_callback)
131 : request_context_(profile->GetRequestContext()),
132 url_(url),
133 timeout_(timeout),
134 java_callback_(java_callback),
135 is_being_destroyed_(false) {
138 void ConnectivityChecker::StartAsyncCheck() {
139 url_fetcher_ =
140 net::URLFetcher::Create(url_, net::URLFetcher::GET, this).Pass();
141 url_fetcher_->SetRequestContext(request_context_);
142 url_fetcher_->SetStopOnRedirect(true);
143 url_fetcher_->SetAutomaticallyRetryOn5xx(false);
144 url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
145 url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
146 net::LOAD_DO_NOT_SAVE_COOKIES |
147 net::LOAD_DO_NOT_SEND_COOKIES |
148 net::LOAD_DO_NOT_SEND_AUTH_DATA);
149 url_fetcher_->Start();
150 expiration_timer_.reset(new base::OneShotTimer<ConnectivityChecker>());
151 expiration_timer_->Start(FROM_HERE, timeout_, this,
152 &ConnectivityChecker::OnTimeout);
155 void ConnectivityChecker::OnTimeout() {
156 if (is_being_destroyed_)
157 return;
158 is_being_destroyed_ = true;
159 url_fetcher_.reset();
160 ExecuteCallback(java_callback_.obj(), CONNECTIVITY_CHECK_RESULT_TIMEOUT);
161 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
164 } // namespace
166 void CheckConnectivity(JNIEnv* env,
167 const JavaParamRef<jclass>& clazz,
168 const JavaParamRef<jobject>& j_profile,
169 const JavaParamRef<jstring>& j_url,
170 jlong j_timeout_ms,
171 const JavaParamRef<jobject>& j_callback) {
172 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
173 if (!profile) {
174 PostCallback(env, j_callback, CONNECTIVITY_CHECK_RESULT_ERROR);
175 return;
177 GURL url(base::android::ConvertJavaStringToUTF8(env, j_url));
178 if (!url.is_valid()) {
179 PostCallback(env, j_callback, CONNECTIVITY_CHECK_RESULT_ERROR);
180 return;
183 // This object will be deleted when the connectivity check has completed.
184 ConnectivityChecker* connectivity_checker = new ConnectivityChecker(
185 profile, url, base::TimeDelta::FromMilliseconds(j_timeout_ms),
186 base::android::ScopedJavaLocalRef<jobject>(env, j_callback));
187 connectivity_checker->StartAsyncCheck();
190 jboolean IsUrlValid(JNIEnv* env,
191 const JavaParamRef<jclass>& clazz,
192 const JavaParamRef<jstring>& j_url) {
193 GURL url(base::android::ConvertJavaStringToUTF8(env, j_url));
194 return url.is_valid();
197 bool RegisterConnectivityChecker(JNIEnv* env) {
198 return RegisterNativesImpl(env);
201 } // namespace android
202 } // namespace chrome