blob: 313f7558bfe7c5a78a5027eb4ab5039038008b6f [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.webkit;
18
19import android.content.Context;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070020import android.util.Log;
21import android.webkit.CookieManager.Cookie;
22
23import java.util.ArrayList;
24import java.util.Iterator;
25
26/**
Mike Hearnadcd2ed2009-01-21 16:44:36 +010027 * The CookieSyncManager is used to synchronize the browser cookie store
28 * between RAM and permanent storage. To get the best performance, browser cookies are
29 * saved in RAM. A separate thread saves the cookies between, driven by a timer.
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070030 * <p>
Mike Hearnadcd2ed2009-01-21 16:44:36 +010031 *
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070032 * To use the CookieSyncManager, the host application has to call the following
Mike Hearnadcd2ed2009-01-21 16:44:36 +010033 * when the application starts:
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070034 * <p>
Mike Hearnadcd2ed2009-01-21 16:44:36 +010035 *
36 * <pre class="prettyprint">CookieSyncManager.createInstance(context)</pre><p>
37 *
38 * To set up for sync, the host application has to call<p>
39 * <pre class="prettyprint">CookieSyncManager.getInstance().startSync()</pre><p>
40 *
41 * in Activity.onResume(), and call
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070042 * <p>
Mike Hearnadcd2ed2009-01-21 16:44:36 +010043 *
44 * <pre class="prettyprint">
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070045 * CookieSyncManager.getInstance().stopSync()
Mike Hearnadcd2ed2009-01-21 16:44:36 +010046 * </pre><p>
47 *
48 * in Activity.onPause().<p>
49 *
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070050 * To get instant sync instead of waiting for the timer to trigger, the host can
51 * call
52 * <p>
Mike Hearnadcd2ed2009-01-21 16:44:36 +010053 * <pre class="prettyprint">CookieSyncManager.getInstance().sync()</pre><p>
54 *
55 * The sync interval is 5 minutes, so you will want to force syncs
56 * manually anyway, for instance in {@link
57 * WebViewClient#onPageFinished}. Note that even sync() happens
58 * asynchronously, so don't do it just as your activity is shutting
59 * down.
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070060 */
61public final class CookieSyncManager extends WebSyncManager {
62
63 private static CookieSyncManager sRef;
64
65 // time when last update happened
66 private long mLastUpdate;
67
68 private CookieSyncManager(Context context) {
69 super(context, "CookieSyncManager");
70 }
71
72 /**
73 * Singleton access to a {@link CookieSyncManager}. An
74 * IllegalStateException will be thrown if
75 * {@link CookieSyncManager#createInstance(Context)} is not called before.
76 *
77 * @return CookieSyncManager
78 */
79 public static synchronized CookieSyncManager getInstance() {
Steve Block82d98162010-10-27 11:29:42 +010080 checkInstanceIsCreated();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070081 return sRef;
82 }
83
84 /**
85 * Create a singleton CookieSyncManager within a context
86 * @param context
87 * @return CookieSyncManager
88 */
89 public static synchronized CookieSyncManager createInstance(
90 Context context) {
Kristian Monsend89a30a2010-11-16 18:11:59 +000091 JniUtil.setContext(context);
Steve Block82d98162010-10-27 11:29:42 +010092 Context appContext = context.getApplicationContext();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070093 if (sRef == null) {
Steve Block82d98162010-10-27 11:29:42 +010094 sRef = new CookieSyncManager(appContext);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070095 }
96 return sRef;
97 }
98
99 /**
Mike Hearnadcd2ed2009-01-21 16:44:36 +0100100 * Package level api, called from CookieManager. Get all the cookies which
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700101 * matches a given base domain.
102 * @param domain
103 * @return A list of Cookie
104 */
105 ArrayList<Cookie> getCookiesForDomain(String domain) {
106 // null mDataBase implies that the host application doesn't support
107 // persistent cookie. No sync needed.
108 if (mDataBase == null) {
109 return new ArrayList<Cookie>();
110 }
111
112 return mDataBase.getCookiesForDomain(domain);
113 }
114
115 /**
116 * Package level api, called from CookieManager Clear all cookies in the
117 * database
118 */
119 void clearAllCookies() {
120 // null mDataBase implies that the host application doesn't support
121 // persistent cookie.
122 if (mDataBase == null) {
123 return;
124 }
125
126 mDataBase.clearCookies();
127 }
128
129 /**
130 * Returns true if there are any saved cookies.
131 */
132 boolean hasCookies() {
133 // null mDataBase implies that the host application doesn't support
134 // persistent cookie.
135 if (mDataBase == null) {
136 return false;
137 }
138
139 return mDataBase.hasCookies();
140 }
141
142 /**
143 * Package level api, called from CookieManager Clear all session cookies in
144 * the database
145 */
146 void clearSessionCookies() {
147 // null mDataBase implies that the host application doesn't support
148 // persistent cookie.
149 if (mDataBase == null) {
150 return;
151 }
152
153 mDataBase.clearSessionCookies();
154 }
155
156 /**
157 * Package level api, called from CookieManager Clear all expired cookies in
158 * the database
159 */
160 void clearExpiredCookies(long now) {
161 // null mDataBase implies that the host application doesn't support
162 // persistent cookie.
163 if (mDataBase == null) {
164 return;
165 }
166
167 mDataBase.clearExpiredCookies(now);
168 }
169
170 protected void syncFromRamToFlash() {
Derek Sollenberger2e5c1502009-06-03 10:44:42 -0400171 if (DebugFlags.COOKIE_SYNC_MANAGER) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700172 Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS");
173 }
174
Iain Merrick99f39772010-12-06 10:44:01 +0000175 CookieManager manager = CookieManager.getInstance();
176
177 if (!manager.acceptCookie()) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700178 return;
179 }
180
Kristian Monsen3e826c92011-02-18 16:01:47 +0000181 if (JniUtil.useChromiumHttpStack()) {
182 manager.flushCookieStore();
183 } else {
184 ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
185 mLastUpdate = System.currentTimeMillis();
186 syncFromRamToFlash(cookieList);
Iain Merrick99f39772010-12-06 10:44:01 +0000187
Kristian Monsen3e826c92011-02-18 16:01:47 +0000188 ArrayList<Cookie> lruList = manager.deleteLRUDomain();
189 syncFromRamToFlash(lruList);
190 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700191
Derek Sollenberger2e5c1502009-06-03 10:44:42 -0400192 if (DebugFlags.COOKIE_SYNC_MANAGER) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700193 Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
194 }
195 }
196
197 private void syncFromRamToFlash(ArrayList<Cookie> list) {
198 Iterator<Cookie> iter = list.iterator();
199 while (iter.hasNext()) {
200 Cookie cookie = iter.next();
201 if (cookie.mode != Cookie.MODE_NORMAL) {
202 if (cookie.mode != Cookie.MODE_NEW) {
203 mDataBase.deleteCookies(cookie.domain, cookie.path,
204 cookie.name);
205 }
206 if (cookie.mode != Cookie.MODE_DELETED) {
207 mDataBase.addCookie(cookie);
208 CookieManager.getInstance().syncedACookie(cookie);
209 } else {
210 CookieManager.getInstance().deleteACookie(cookie);
211 }
212 }
213 }
214 }
Steve Block82d98162010-10-27 11:29:42 +0100215
216 private static void checkInstanceIsCreated() {
217 if (sRef == null) {
218 throw new IllegalStateException(
219 "CookieSyncManager::createInstance() needs to be called "
220 + "before CookieSyncManager::getInstance()");
221 }
222 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700223}