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

Side by Side Diff: android_webview/native/cookie_manager.cc

Issue 10913074: Add WebView implementation for CookieManager. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebased Created 8 years, 3 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
« no previous file with comments | « android_webview/native/cookie_manager.h ('k') | android_webview/native/webview_native.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "android_webview/native/cookie_manager.h"
6
7 #include "android_webview/browser/aw_cookie_access_policy.h"
8 #include "android_webview/native/aw_browser_dependency_factory.h"
9 #include "base/android/jni_string.h"
10 #include "base/bind.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/cookies/cookie_monster.h"
16 #include "net/cookies/cookie_options.h"
17 #include "net/cookies/cookie_store.h"
18 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "jni/CookieManager_jni.h"
21
22 using base::android::ConvertJavaStringToUTF8;
23 using base::android::ConvertJavaStringToUTF16;
24 using content::BrowserThread;
25 using net::CookieList;
26 using net::CookieMonster;
27 using net::URLRequestContextGetter;
28
29 // This class is only available when building the chromium back-end for andriod
30 // webview: it is required where API backward compatibility demands that the UI
31 // thread must block waiting on other threads e.g. to obtain a synchronous
32 // return value. Long term, asynchronous overloads of all such methods will be
33 // added in the public API, and and no new uses of this will be allowed.
34 class ScopedAllowWaitForLegacyWebViewApi {
35 private:
36 base::ThreadRestrictions::ScopedAllowWait wait;
37 };
38
39 // CookieManager should be refactored to not require all tasks accessing the
40 // CookieStore to be piped through the IO thread. It is currently required as
41 // the URLRequestContext provides the easiest mechanism for accessing the
42 // CookieStore, but the CookieStore is threadsafe. In the future, we may
43 // instead want to inject an explicit CookieStore dependency into this object
44 // during process initialization to avoid depending on the URLRequestContext.
45 //
46 // In addition to the IO thread being the easiest access mechanism, it is also
47 // used because the async cookie tasks need to be processed on a different
48 // thread than the caller from Java, which can be any thread. But, the calling
49 // thread will be 'dead' blocked waiting on the async task to complete, so we
50 // need it to complete on a 'live' (non-blocked) thread that is still pumping
51 // messages.
52 //
53 // We could refactor to only provide an asynchronous (but thread safe) API on
54 // the native side, and move this support for legacy synchronous blocking
55 // messages into a java-side worker thread.
56
57 namespace android_webview {
58
59 namespace {
60
61 typedef base::Callback<void(scoped_refptr<URLRequestContextGetter>,
62 base::WaitableEvent*)> CookieTask;
63
64 // Executes the |callback| task on the IO thread and |wait_for_completion|
65 // should only be true if the Java API method returns a value or is explicitly
66 // stated to be synchronous.
67 static void ExecCookieTask(const CookieTask& callback,
68 const bool wait_for_completion) {
69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70
71 content::BrowserContext* context =
72 android_webview::AwBrowserDependencyFactory::GetInstance()->
73 GetBrowserContext(false);
74 if (!context)
75 return;
76
77 scoped_refptr<URLRequestContextGetter> context_getter(
78 context->GetRequestContext());
79
80 if (wait_for_completion) {
81 base::WaitableEvent completion(false, false);
82
83 context->GetRequestContext()->GetNetworkTaskRunner()->PostTask(
84 FROM_HERE, base::Bind(callback, context_getter, &completion));
85
86 ScopedAllowWaitForLegacyWebViewApi wait;
87 completion.Wait();
88 } else {
89 base::WaitableEvent* cb = NULL;
90 context->GetRequestContext()->GetNetworkTaskRunner()->PostTask(
91 FROM_HERE, base::Bind(callback, context_getter, cb));
92 }
93 }
94
95 } // namespace
96
97 static void SetAcceptCookie(JNIEnv* env, jobject obj, jboolean accept) {
98 AwCookieAccessPolicy::GetInstance()->SetGlobalAllowAccess(accept);
99 }
100
101 static jboolean AcceptCookie(JNIEnv* env, jobject obj) {
102 return AwCookieAccessPolicy::GetInstance()->GetGlobalAllowAccess();
103 }
104
105 namespace {
106
107 // The CookieManager API does not return a value for SetCookie,
108 // so we don't need to propagate the |success| value back to the caller.
109 static void SetCookieCompleted(bool success) {
110 }
111
112 static void SetCookieAsyncHelper(
113 const GURL& host,
114 const std::string& value,
115 scoped_refptr<URLRequestContextGetter> context_getter,
116 base::WaitableEvent* completion) {
117 DCHECK(!completion);
118 net::CookieOptions options;
119 options.set_include_httponly();
120
121 context_getter->GetURLRequestContext()->cookie_store()->
122 SetCookieWithOptionsAsync(host, value, options,
123 base::Bind(&SetCookieCompleted));
124 }
125
126 } // namespace
127
128 static void SetCookie(JNIEnv* env, jobject obj, jstring url, jstring value) {
129 GURL host(ConvertJavaStringToUTF16(env, url));
130 std::string cookie_value(ConvertJavaStringToUTF8(env, value));
131
132 ExecCookieTask(base::Bind(&SetCookieAsyncHelper, host, cookie_value), false);
133 }
134
135 namespace {
136
137 static void GetCookieValueCompleted(base::WaitableEvent* completion,
138 std::string* result,
139 const std::string& value) {
140 *result = value;
141 DCHECK(completion);
142 completion->Signal();
143 }
144
145 static void GetCookieValueAsyncHelper(
146 const GURL& host,
147 std::string* result,
148 scoped_refptr<URLRequestContextGetter> context_getter,
149 base::WaitableEvent* completion) {
150
151 net::CookieOptions options;
152 options.set_include_httponly();
153
154 context_getter->GetURLRequestContext()->cookie_store()->
155 GetCookiesWithOptionsAsync(host, options,
156 base::Bind(&GetCookieValueCompleted,
157 completion,
158 result));
159 }
160
161 } // namespace
162
163 static jstring GetCookie(JNIEnv* env, jobject obj, jstring url) {
164 GURL host(ConvertJavaStringToUTF16(env, url));
165 std::string cookie_value;
166 ExecCookieTask(base::Bind(&GetCookieValueAsyncHelper, host, &cookie_value),
167 true);
168
169 return base::android::ConvertUTF8ToJavaString(env, cookie_value).Release();
170 }
171
172 namespace {
173
174 static void RemoveSessionCookieCompleted(int num_deleted) {
175 // The CookieManager API does not return a value for removeSessionCookie,
176 // so we don't need to propagate the |num_deleted| value back to the caller.
177 }
178
179 static void RemoveSessionCookieAsyncHelper(
180 scoped_refptr<URLRequestContextGetter> context_getter,
181 base::WaitableEvent* completion) {
182 DCHECK(!completion);
183 net::CookieOptions options;
184 options.set_include_httponly();
185
186 CookieMonster* monster = context_getter->GetURLRequestContext()->
187 cookie_store()->GetCookieMonster();
188 monster->DeleteSessionCookiesAsync(base::Bind(&RemoveSessionCookieCompleted));
189 }
190
191 } // namespace
192
193 static void RemoveSessionCookie(JNIEnv* env, jobject obj) {
194 ExecCookieTask(base::Bind(&RemoveSessionCookieAsyncHelper), false);
195 }
196
197 namespace {
198
199 static void RemoveAllCookieCompleted(int num_deleted) {
200 // The CookieManager API does not return a value for removeAllCookie,
201 // so we don't need to propagate the |num_deleted| value back to the caller.
202 }
203
204 static void RemoveAllCookieAsyncHelper(
205 scoped_refptr<URLRequestContextGetter> context_getter,
206 base::WaitableEvent* completion) {
207 DCHECK(!completion);
208 CookieMonster* monster = context_getter->GetURLRequestContext()->
209 cookie_store()->GetCookieMonster();
210 monster->DeleteAllAsync(base::Bind(&RemoveAllCookieCompleted));
211 }
212
213 } // namespace
214
215 static void RemoveAllCookie(JNIEnv* env, jobject obj) {
216 ExecCookieTask(base::Bind(&RemoveAllCookieAsyncHelper), false);
217 }
218
219 static void RemoveExpiredCookie(JNIEnv* env, jobject obj) {
220 // HasCookies will call GetAllCookiesAsync, which in turn will force a GC.
221 HasCookies(env, obj);
222 }
223
224 namespace {
225
226 static void HasCookiesCompleted(base::WaitableEvent* completion,
227 bool* result,
228 const CookieList& cookies) {
229 *result = cookies.size() != 0;
230 DCHECK(completion);
231 completion->Signal();
232 }
233
234 static void HasCookiesAsyncHelper(
235 bool* result,
236 scoped_refptr<URLRequestContextGetter> context_getter,
237 base::WaitableEvent* completion) {
238
239 CookieMonster* monster = context_getter->GetURLRequestContext()->
240 cookie_store()->GetCookieMonster();
241 monster->GetAllCookiesAsync(base::Bind(&HasCookiesCompleted, completion,
242 result));
243 }
244
245 } // namespace
246
247 static jboolean HasCookies(JNIEnv* env, jobject obj) {
248 bool has_cookies;
249 ExecCookieTask(base::Bind(&HasCookiesAsyncHelper, &has_cookies), true);
250 return has_cookies;
251 }
252
253 namespace {
254
255 static void AllowFileSchemeCookiesAsyncHelper(
256 bool* accept,
257 scoped_refptr<URLRequestContextGetter> context_getter,
258 base::WaitableEvent* completion) {
259
260 CookieMonster* monster = context_getter->GetURLRequestContext()->
261 cookie_store()->GetCookieMonster();
262 *accept = monster->IsCookieableScheme("file");
263
264 DCHECK(completion);
265 completion->Signal();
266 }
267
268 } // namespace
269
270 static jboolean AllowFileSchemeCookies(JNIEnv* env, jclass obj) {
271 bool accept;
272 ExecCookieTask(base::Bind(&AllowFileSchemeCookiesAsyncHelper, &accept), true);
273 return accept;
274 }
275
276 namespace {
277
278 static void SetAcceptFileSchemeCookiesAsyncHelper(
279 bool accept,
280 scoped_refptr<URLRequestContextGetter> context_getter,
281 base::WaitableEvent* completion) {
282
283 CookieMonster* monster = context_getter->GetURLRequestContext()->
284 cookie_store()->GetCookieMonster();
285 monster->SetEnableFileScheme(accept);
286
287 DCHECK(completion);
288 completion->Signal();
289 }
290
291 } // namespace
292
293 static void SetAcceptFileSchemeCookies(JNIEnv* env, jclass obj,
294 jboolean accept) {
295 ExecCookieTask(base::Bind(&SetAcceptFileSchemeCookiesAsyncHelper, accept),
296 true);
297 }
298
299 bool RegisterCookieManager(JNIEnv* env) {
300 return RegisterNativesImpl(env);
301 }
302
303 } // android_webview namespace
OLDNEW
« no previous file with comments | « android_webview/native/cookie_manager.h ('k') | android_webview/native/webview_native.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698