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