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

Side by Side 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: Fix all tests and add temporary server fix 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 unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/android/feedback/connectivity_checker.h"
6
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"
23
24 namespace chrome {
25 namespace android {
26
27 namespace {
28
29 void ExecuteCallback(jobject callback, bool connected) {
30 Java_ConnectivityChecker_executeCallback(base::android::AttachCurrentThread(),
31 callback, connected);
32 }
33
34 void ExecuteCallbackFromRef(
35 base::android::ScopedJavaGlobalRef<jobject>* callback,
36 bool connected) {
37 ExecuteCallback(callback->obj(), connected);
38 }
39
40 void PostCallback(JNIEnv* env, jobject j_callback, bool connected) {
41 base::android::ScopedJavaGlobalRef<jobject>* callback =
42 new base::android::ScopedJavaGlobalRef<jobject>();
cjhopman 2015/05/07 00:09:09 You can just pass the j_callback to the constructo
nyquist 2015/05/07 05:35:46 I for some reason could not get that to work. Happ
cjhopman 2015/05/08 18:58:39 I'd say you should just add the appropriate constr
nyquist 2015/05/12 00:42:30 Done.
43 callback->Reset(env, j_callback);
44 base::MessageLoop::current()->PostTask(
45 FROM_HERE,
46 base::Bind(&ExecuteCallbackFromRef, base::Owned(callback), connected));
47 }
48
49 // A utility class for checking if the device is currently connected to the
50 // Internet.
51 class ConnectivityChecker : public net::URLFetcherDelegate {
52 public:
53 ConnectivityChecker(Profile* profile,
54 const GURL& url,
55 const base::TimeDelta& timeout,
56 const base::android::JavaRef<jobject>& java_callback);
57
58 // Kicks off the asynchronous connectivity check. When the request has
59 // completed, |this| is deleted.
60 void StartAsyncCheck();
61
62 // net::URLFetcherDelegate implementation:
63 void OnURLFetchComplete(const net::URLFetcher* source) override;
64
65 // Cancels the URLFetcher, and triggers the callback with a negative result.
66 void Cancel();
67
68 private:
69 // The context in which the connectivity check is performed.
70 net::URLRequestContextGetter* request_context_;
71
72 // The URL to connect to.
73 const GURL& url_;
74
75 // How long to wait for a response before giving up.
76 const base::TimeDelta& timeout_;
77
78 // Holds the Java object which will get the callback with the result.
79 base::android::ScopedJavaGlobalRef<jobject> java_callback_;
80
81 // The URLFetcher that executes the connectivity check.
82 scoped_ptr<net::URLFetcher> url_fetcher_;
83
84 scoped_ptr<base::OneShotTimer<ConnectivityChecker>> expiration_timer_;
85 };
86
87 void ConnectivityChecker::OnURLFetchComplete(const net::URLFetcher* source) {
88 DCHECK_EQ(url_fetcher_.get(), source);
89
90 net::URLRequestStatus status = source->GetStatus();
91 int response_code = source->GetResponseCode();
92
93 bool connected = status.is_success() && response_code == net::HTTP_NO_CONTENT;
94 ExecuteCallback(java_callback_.obj(), connected);
95
96 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
cjhopman 2015/05/07 00:09:10 There's a race here that could cause a double dele
nyquist 2015/05/07 05:35:46 Doh! Thanks. Added a boolean to track the destruc
97 }
98
99 ConnectivityChecker::ConnectivityChecker(
100 Profile* profile,
101 const GURL& url,
102 const base::TimeDelta& timeout,
103 const base::android::JavaRef<jobject>& java_callback)
104 : request_context_(profile->GetRequestContext()),
105 url_(url),
106 timeout_(timeout),
107 java_callback_(java_callback) {
108 }
109
110 void ConnectivityChecker::StartAsyncCheck() {
111 url_fetcher_ =
112 net::URLFetcher::Create(url_, net::URLFetcher::GET, this).Pass();
113 url_fetcher_->SetRequestContext(request_context_);
114 url_fetcher_->SetStopOnRedirect(true);
115 url_fetcher_->SetAutomaticallyRetryOn5xx(false);
116 url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
117 url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
118 net::LOAD_DO_NOT_SAVE_COOKIES |
119 net::LOAD_DO_NOT_SEND_COOKIES |
120 net::LOAD_DO_NOT_SEND_AUTH_DATA);
121 url_fetcher_->Start();
122 expiration_timer_.reset(new base::OneShotTimer<ConnectivityChecker>());
123 expiration_timer_->Start(FROM_HERE, timeout_, this,
124 &ConnectivityChecker::Cancel);
125 }
126
127 void ConnectivityChecker::Cancel() {
128 url_fetcher_.reset();
129 ExecuteCallback(java_callback_.obj(), false);
130 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
131 }
132
133 } // namespace
134
135 void CheckConnectivity(JNIEnv* env,
136 jclass clazz,
137 jobject j_profile,
138 jstring j_url,
139 jlong j_timeout_ms,
140 jobject j_callback) {
141 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
142 if (!profile) {
143 PostCallback(env, j_callback, false);
144 return;
145 }
146 GURL url(base::android::ConvertJavaStringToUTF8(env, j_url));
147 if (!url.is_valid()) {
148 PostCallback(env, j_callback, false);
149 return;
150 }
151
152 // This object will be deleted when the connectivity check has completed.
153 ConnectivityChecker* connectivity_checker = new ConnectivityChecker(
154 profile, url, base::TimeDelta::FromMilliseconds(j_timeout_ms),
155 base::android::ScopedJavaLocalRef<jobject>(env, j_callback));
156 connectivity_checker->StartAsyncCheck();
157 }
158
159 bool RegisterConnectivityChecker(JNIEnv* env) {
160 return RegisterNativesImpl(env);
161 }
162
163 } // namespace android
164 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698