CookieSyncManager.java revision adcd2ed8d24deddee528e96260d0ed673eeb261c
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.Config; 21import android.util.Log; 22import android.webkit.CookieManager.Cookie; 23 24import java.util.ArrayList; 25import java.util.Iterator; 26 27/** 28 * The CookieSyncManager is used to synchronize the browser cookie store 29 * between RAM and permanent storage. To get the best performance, browser cookies are 30 * saved in RAM. A separate thread saves the cookies between, driven by a timer. 31 * <p> 32 * 33 * To use the CookieSyncManager, the host application has to call the following 34 * when the application starts: 35 * <p> 36 * 37 * <pre class="prettyprint">CookieSyncManager.createInstance(context)</pre><p> 38 * 39 * To set up for sync, the host application has to call<p> 40 * <pre class="prettyprint">CookieSyncManager.getInstance().startSync()</pre><p> 41 * 42 * in Activity.onResume(), and call 43 * <p> 44 * 45 * <pre class="prettyprint"> 46 * CookieSyncManager.getInstance().stopSync() 47 * </pre><p> 48 * 49 * in Activity.onPause().<p> 50 * 51 * To get instant sync instead of waiting for the timer to trigger, the host can 52 * call 53 * <p> 54 * <pre class="prettyprint">CookieSyncManager.getInstance().sync()</pre><p> 55 * 56 * The sync interval is 5 minutes, so you will want to force syncs 57 * manually anyway, for instance in {@link 58 * WebViewClient#onPageFinished}. Note that even sync() happens 59 * asynchronously, so don't do it just as your activity is shutting 60 * down. 61 */ 62public final class CookieSyncManager extends WebSyncManager { 63 64 private static CookieSyncManager sRef; 65 66 // time when last update happened 67 private long mLastUpdate; 68 69 private CookieSyncManager(Context context) { 70 super(context, "CookieSyncManager"); 71 } 72 73 /** 74 * Singleton access to a {@link CookieSyncManager}. An 75 * IllegalStateException will be thrown if 76 * {@link CookieSyncManager#createInstance(Context)} is not called before. 77 * 78 * @return CookieSyncManager 79 */ 80 public static synchronized CookieSyncManager getInstance() { 81 if (sRef == null) { 82 throw new IllegalStateException( 83 "CookieSyncManager::createInstance() needs to be called " 84 + "before CookieSyncManager::getInstance()"); 85 } 86 return sRef; 87 } 88 89 /** 90 * Create a singleton CookieSyncManager within a context 91 * @param context 92 * @return CookieSyncManager 93 */ 94 public static synchronized CookieSyncManager createInstance( 95 Context context) { 96 if (sRef == null) { 97 sRef = new CookieSyncManager(context); 98 } 99 return sRef; 100 } 101 102 /** 103 * Package level api, called from CookieManager. Get all the cookies which 104 * matches a given base domain. 105 * @param domain 106 * @return A list of Cookie 107 */ 108 ArrayList<Cookie> getCookiesForDomain(String domain) { 109 // null mDataBase implies that the host application doesn't support 110 // persistent cookie. No sync needed. 111 if (mDataBase == null) { 112 return new ArrayList<Cookie>(); 113 } 114 115 return mDataBase.getCookiesForDomain(domain); 116 } 117 118 /** 119 * Package level api, called from CookieManager Clear all cookies in the 120 * database 121 */ 122 void clearAllCookies() { 123 // null mDataBase implies that the host application doesn't support 124 // persistent cookie. 125 if (mDataBase == null) { 126 return; 127 } 128 129 mDataBase.clearCookies(); 130 } 131 132 /** 133 * Returns true if there are any saved cookies. 134 */ 135 boolean hasCookies() { 136 // null mDataBase implies that the host application doesn't support 137 // persistent cookie. 138 if (mDataBase == null) { 139 return false; 140 } 141 142 return mDataBase.hasCookies(); 143 } 144 145 /** 146 * Package level api, called from CookieManager Clear all session cookies in 147 * the database 148 */ 149 void clearSessionCookies() { 150 // null mDataBase implies that the host application doesn't support 151 // persistent cookie. 152 if (mDataBase == null) { 153 return; 154 } 155 156 mDataBase.clearSessionCookies(); 157 } 158 159 /** 160 * Package level api, called from CookieManager Clear all expired cookies in 161 * the database 162 */ 163 void clearExpiredCookies(long now) { 164 // null mDataBase implies that the host application doesn't support 165 // persistent cookie. 166 if (mDataBase == null) { 167 return; 168 } 169 170 mDataBase.clearExpiredCookies(now); 171 } 172 173 protected void syncFromRamToFlash() { 174 if (Config.LOGV) { 175 Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS"); 176 } 177 178 if (!CookieManager.getInstance().acceptCookie()) { 179 return; 180 } 181 182 ArrayList<Cookie> cookieList = CookieManager.getInstance() 183 .getUpdatedCookiesSince(mLastUpdate); 184 mLastUpdate = System.currentTimeMillis(); 185 syncFromRamToFlash(cookieList); 186 187 ArrayList<Cookie> lruList = 188 CookieManager.getInstance().deleteLRUDomain(); 189 syncFromRamToFlash(lruList); 190 191 if (Config.LOGV) { 192 Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE"); 193 } 194 } 195 196 private void syncFromRamToFlash(ArrayList<Cookie> list) { 197 Iterator<Cookie> iter = list.iterator(); 198 while (iter.hasNext()) { 199 Cookie cookie = iter.next(); 200 if (cookie.mode != Cookie.MODE_NORMAL) { 201 if (cookie.mode != Cookie.MODE_NEW) { 202 mDataBase.deleteCookies(cookie.domain, cookie.path, 203 cookie.name); 204 } 205 if (cookie.mode != Cookie.MODE_DELETED) { 206 mDataBase.addCookie(cookie); 207 CookieManager.getInstance().syncedACookie(cookie); 208 } else { 209 CookieManager.getInstance().deleteACookie(cookie); 210 } 211 } 212 } 213 } 214} 215