CookieSyncManager.java revision 2e5c150e746647a1ce5c10e1708debbf06c45ea7
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 17package android.webkit; 18 19import android.content.Context; 20import android.util.Log; 21import android.webkit.CookieManager.Cookie; 22 23import java.util.ArrayList; 24import 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 */ 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() { 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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