OSDN Git Service

Decouple construction of WebView, CookieSyncManager, WebViewDatabase
authorJonathan Dixon <joth@google.com>
Thu, 3 Oct 2013 10:03:31 +0000 (11:03 +0100)
committerJonathan Dixon <joth@google.com>
Thu, 3 Oct 2013 16:53:33 +0000 (17:53 +0100)
Bug 10932261

Most of this flow exists purely to get the Context from
CookieSyncManager.createInstance over to WebViewDatabaseClassic. Make
that depenency more explicit (with a TODO to remove it) and this allows
a much simpler CookieSyncManager implementation for the normal case.
Note after this patch, CookieSyncManager.getInstance() is technically fine
to call without a prior call to createInstance, but retaining the
ordering requirement as a convenience for anyone developing on new OS
but still supporting the older versions.
(Note that CookieSyncManager instance is not required for correct
operation of either existing webview, so these changes only impact
the public API contract of object lifetimes, not the underlying
implementation)

Change-Id: I51fdd6622704f1c749277fee6df2f84ac4c704d2

core/java/android/webkit/CookieSyncManager.java
core/java/android/webkit/WebSyncManager.java
core/java/android/webkit/WebView.java

index 276bcae..13aa43f 100644 (file)
@@ -59,8 +59,10 @@ public final class CookieSyncManager extends WebSyncManager {
 
     private static CookieSyncManager sRef;
 
-    private CookieSyncManager(Context context) {
-        super(context, "CookieSyncManager");
+    private static boolean sGetInstanceAllowed = false;
+
+    private CookieSyncManager() {
+        super("CookieSyncManager");
     }
 
     /**
@@ -71,7 +73,10 @@ public final class CookieSyncManager extends WebSyncManager {
      * @return CookieSyncManager
      */
     public static synchronized CookieSyncManager getInstance() {
-        checkInstanceIsCreated();
+        checkInstanceIsAllowed();
+        if (sRef == null) {
+            sRef = new CookieSyncManager();
+        }
         return sRef;
     }
 
@@ -80,16 +85,13 @@ public final class CookieSyncManager extends WebSyncManager {
      * @param context
      * @return CookieSyncManager
      */
-    public static synchronized CookieSyncManager createInstance(
-            Context context) {
+    public static synchronized CookieSyncManager createInstance(Context context) {
         if (context == null) {
             throw new IllegalArgumentException("Invalid context argument");
         }
 
-        if (sRef == null) {
-            sRef = new CookieSyncManager(context);
-        }
-        return sRef;
+        setGetInstanceIsAllowed();
+        return getInstance();
     }
 
     protected void syncFromRamToFlash() {
@@ -110,8 +112,15 @@ public final class CookieSyncManager extends WebSyncManager {
         }
     }
 
-    private static void checkInstanceIsCreated() {
-        if (sRef == null) {
+    static void setGetInstanceIsAllowed() {
+        sGetInstanceAllowed = true;
+    }
+
+    private static void checkInstanceIsAllowed() {
+        // Prior to Android KK, calling createInstance() or constructing a WebView is
+        // a hard pre-condition for calling getInstance(). We retain that contract to aid
+        // developers targeting a range of SDK levels.
+        if (!sGetInstanceAllowed) {
             throw new IllegalStateException(
                     "CookieSyncManager::createInstance() needs to be called "
                             + "before CookieSyncManager::getInstance()");
index d3ec603..c600a7e 100644 (file)
@@ -36,7 +36,7 @@ abstract class WebSyncManager implements Runnable {
     private String mThreadName;
     // handler of the sync thread
     protected Handler mHandler;
-    // database for the persistent storage
+    // database for the persistent storage. Always null.
     protected WebViewDatabase mDataBase;
     // Ref count for calls to start/stop sync
     private int mStartSyncRefCount;
@@ -60,16 +60,15 @@ abstract class WebSyncManager implements Runnable {
     }
 
     protected WebSyncManager(Context context, String name) {
+        this(name);
+    }
+
+    /** @hide */
+    WebSyncManager(String name) {
         mThreadName = name;
-        if (context != null) {
-            mDataBase = WebViewDatabase.getInstance(context);
-            mSyncThread = new Thread(this);
-            mSyncThread.setName(mThreadName);
-            mSyncThread.start();
-        } else {
-            throw new IllegalStateException(
-                    "WebSyncManager can't be created without context");
-        }
+        mSyncThread = new Thread(this);
+        mSyncThread.setName(mThreadName);
+        mSyncThread.start();
     }
 
     protected Object clone() throws CloneNotSupportedException {
@@ -82,7 +81,7 @@ abstract class WebSyncManager implements Runnable {
         mHandler = new SyncHandler();
         onSyncInit();
         // lower the priority after onSyncInit() is done
-       Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
 
         Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
         mHandler.sendMessageDelayed(msg, SYNC_LATER_INTERVAL);
index 90cc72e..2cbe0e2 100644 (file)
@@ -506,8 +506,8 @@ public class WebView extends AbsoluteLayout
 
         ensureProviderCreated();
         mProvider.init(javaScriptInterfaces, privateBrowsing);
-        // Post condition of creating a webview is the CookieSyncManager instance exists.
-        CookieSyncManager.createInstance(getContext());
+        // Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
+        CookieSyncManager.setGetInstanceIsAllowed();
     }
 
     /**