• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.webkit;
18 
19 import android.content.Context;
20 import android.util.Log;
21 import android.webkit.CookieManager.Cookie;
22 
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 
26 /**
27  * 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.
30  * <p>
31  *
32  * To use the CookieSyncManager, the host application has to call the following
33  * when the application starts:
34  * <p>
35  *
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
42  * <p>
43  *
44  * <pre class="prettyprint">
45  * CookieSyncManager.getInstance().stopSync()
46  * </pre><p>
47  *
48  * in Activity.onPause().<p>
49  *
50  * To get instant sync instead of waiting for the timer to trigger, the host can
51  * call
52  * <p>
53  * <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.
60  */
61 public final class CookieSyncManager extends WebSyncManager {
62 
63     private static CookieSyncManager sRef;
64 
65     // time when last update happened
66     private long mLastUpdate;
67 
CookieSyncManager(Context context)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      */
getInstance()79     public static synchronized CookieSyncManager getInstance() {
80         if (sRef == null) {
81             throw new IllegalStateException(
82                     "CookieSyncManager::createInstance() needs to be called "
83                             + "before CookieSyncManager::getInstance()");
84         }
85         return sRef;
86     }
87 
88     /**
89      * Create a singleton CookieSyncManager within a context
90      * @param context
91      * @return CookieSyncManager
92      */
createInstance( Context context)93     public static synchronized CookieSyncManager createInstance(
94             Context context) {
95         if (sRef == null) {
96             sRef = new CookieSyncManager(context);
97         }
98         return sRef;
99     }
100 
101     /**
102      * Package level api, called from CookieManager. Get all the cookies which
103      * matches a given base domain.
104      * @param domain
105      * @return A list of Cookie
106      */
getCookiesForDomain(String domain)107     ArrayList<Cookie> getCookiesForDomain(String domain) {
108         // null mDataBase implies that the host application doesn't support
109         // persistent cookie. No sync needed.
110         if (mDataBase == null) {
111             return new ArrayList<Cookie>();
112         }
113 
114         return mDataBase.getCookiesForDomain(domain);
115     }
116 
117     /**
118      * Package level api, called from CookieManager Clear all cookies in the
119      * database
120      */
clearAllCookies()121     void clearAllCookies() {
122         // null mDataBase implies that the host application doesn't support
123         // persistent cookie.
124         if (mDataBase == null) {
125             return;
126         }
127 
128         mDataBase.clearCookies();
129     }
130 
131     /**
132      * Returns true if there are any saved cookies.
133      */
hasCookies()134     boolean hasCookies() {
135         // null mDataBase implies that the host application doesn't support
136         // persistent cookie.
137         if (mDataBase == null) {
138             return false;
139         }
140 
141         return mDataBase.hasCookies();
142     }
143 
144     /**
145      * Package level api, called from CookieManager Clear all session cookies in
146      * the database
147      */
clearSessionCookies()148     void clearSessionCookies() {
149         // null mDataBase implies that the host application doesn't support
150         // persistent cookie.
151         if (mDataBase == null) {
152             return;
153         }
154 
155         mDataBase.clearSessionCookies();
156     }
157 
158     /**
159      * Package level api, called from CookieManager Clear all expired cookies in
160      * the database
161      */
clearExpiredCookies(long now)162     void clearExpiredCookies(long now) {
163         // null mDataBase implies that the host application doesn't support
164         // persistent cookie.
165         if (mDataBase == null) {
166             return;
167         }
168 
169         mDataBase.clearExpiredCookies(now);
170     }
171 
syncFromRamToFlash()172     protected void syncFromRamToFlash() {
173         if (DebugFlags.COOKIE_SYNC_MANAGER) {
174             Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS");
175         }
176 
177         if (!CookieManager.getInstance().acceptCookie()) {
178             return;
179         }
180 
181         ArrayList<Cookie> cookieList = CookieManager.getInstance()
182                 .getUpdatedCookiesSince(mLastUpdate);
183         mLastUpdate = System.currentTimeMillis();
184         syncFromRamToFlash(cookieList);
185 
186         ArrayList<Cookie> lruList =
187                 CookieManager.getInstance().deleteLRUDomain();
188         syncFromRamToFlash(lruList);
189 
190         if (DebugFlags.COOKIE_SYNC_MANAGER) {
191             Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
192         }
193     }
194 
syncFromRamToFlash(ArrayList<Cookie> list)195     private void syncFromRamToFlash(ArrayList<Cookie> list) {
196         Iterator<Cookie> iter = list.iterator();
197         while (iter.hasNext()) {
198             Cookie cookie = iter.next();
199             if (cookie.mode != Cookie.MODE_NORMAL) {
200                 if (cookie.mode != Cookie.MODE_NEW) {
201                     mDataBase.deleteCookies(cookie.domain, cookie.path,
202                             cookie.name);
203                 }
204                 if (cookie.mode != Cookie.MODE_DELETED) {
205                     mDataBase.addCookie(cookie);
206                     CookieManager.getInstance().syncedACookie(cookie);
207                 } else {
208                     CookieManager.getInstance().deleteACookie(cookie);
209                 }
210             }
211         }
212     }
213 }
214