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