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