154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/* 254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License. 654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at 754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and 1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License. 1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpackage android.webkit; 1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context; 2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Log; 2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/** 24adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * The CookieSyncManager is used to synchronize the browser cookie store 25adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * between RAM and permanent storage. To get the best performance, browser cookies are 26adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * saved in RAM. A separate thread saves the cookies between, driven by a timer. 2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p> 28adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * To use the CookieSyncManager, the host application has to call the following 30adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * when the application starts: 3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p> 32adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 33adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * <pre class="prettyprint">CookieSyncManager.createInstance(context)</pre><p> 34adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 35adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * To set up for sync, the host application has to call<p> 36adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * <pre class="prettyprint">CookieSyncManager.getInstance().startSync()</pre><p> 37adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 38adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * in Activity.onResume(), and call 3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p> 40adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 41adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * <pre class="prettyprint"> 4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * CookieSyncManager.getInstance().stopSync() 43adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * </pre><p> 44adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 45adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * in Activity.onPause().<p> 46adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * To get instant sync instead of waiting for the timer to trigger, the host can 4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * call 4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p> 50adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * <pre class="prettyprint">CookieSyncManager.getInstance().sync()</pre><p> 51adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * 52adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * The sync interval is 5 minutes, so you will want to force syncs 53adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * manually anyway, for instance in {@link 54adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * WebViewClient#onPageFinished}. Note that even sync() happens 55adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * asynchronously, so don't do it just as your activity is shutting 56adcd2ed8d24deddee528e96260d0ed673eeb261cMike Hearn * down. 5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic final class CookieSyncManager extends WebSyncManager { 5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private static CookieSyncManager sRef; 6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 62eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon private static boolean sGetInstanceAllowed = false; 63eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon 64eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon private CookieSyncManager() { 65eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon super("CookieSyncManager"); 6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Singleton access to a {@link CookieSyncManager}. An 7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * IllegalStateException will be thrown if 7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link CookieSyncManager#createInstance(Context)} is not called before. 7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @return CookieSyncManager 7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public static synchronized CookieSyncManager getInstance() { 76eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon checkInstanceIsAllowed(); 77eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon if (sRef == null) { 78eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon sRef = new CookieSyncManager(); 79eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon } 8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return sRef; 8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Create a singleton CookieSyncManager within a context 8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @param context 8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @return CookieSyncManager 8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 88eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon public static synchronized CookieSyncManager createInstance(Context context) { 8987af7314d4319a0ccaaf466a25e3fe4f416cc953Kristian Monsen if (context == null) { 9087af7314d4319a0ccaaf466a25e3fe4f416cc953Kristian Monsen throw new IllegalArgumentException("Invalid context argument"); 9187af7314d4319a0ccaaf466a25e3fe4f416cc953Kristian Monsen } 9287af7314d4319a0ccaaf466a25e3fe4f416cc953Kristian Monsen 93eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon setGetInstanceIsAllowed(); 94eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon return getInstance(); 9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void syncFromRamToFlash() { 982e5c150e746647a1ce5c10e1708debbf06c45ea7Derek Sollenberger if (DebugFlags.COOKIE_SYNC_MANAGER) { 9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS"); 10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10299f39771ab15fc13d221ebfb3682741002c5f7b1Iain Merrick CookieManager manager = CookieManager.getInstance(); 10399f39771ab15fc13d221ebfb3682741002c5f7b1Iain Merrick 10499f39771ab15fc13d221ebfb3682741002c5f7b1Iain Merrick if (!manager.acceptCookie()) { 10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return; 10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1080acb1c32fa002a648c8090f622b0094f406d5411Steve Block manager.flushCookieStore(); 10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1102e5c150e746647a1ce5c10e1708debbf06c45ea7Derek Sollenberger if (DebugFlags.COOKIE_SYNC_MANAGER) { 11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE"); 11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 115eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon static void setGetInstanceIsAllowed() { 116eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon sGetInstanceAllowed = true; 117eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon } 118eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon 119eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon private static void checkInstanceIsAllowed() { 120eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon // Prior to Android KK, calling createInstance() or constructing a WebView is 121eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon // a hard pre-condition for calling getInstance(). We retain that contract to aid 122eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon // developers targeting a range of SDK levels. 123eb9e801424005756f319d91493386b9a4f180921Jonathan Dixon if (!sGetInstanceAllowed) { 12482d98161362750ed280675b704a5ae467091cfbaSteve Block throw new IllegalStateException( 12582d98161362750ed280675b704a5ae467091cfbaSteve Block "CookieSyncManager::createInstance() needs to be called " 12682d98161362750ed280675b704a5ae467091cfbaSteve Block + "before CookieSyncManager::getInstance()"); 12782d98161362750ed280675b704a5ae467091cfbaSteve Block } 12882d98161362750ed280675b704a5ae467091cfbaSteve Block } 12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project} 130