Add a method to override all the cookies in CookieMonster

This method is required in order to upstream CookieStoreIOS.

CookieStoreIOS can periodically synchronize the iOS system
cookie store (NSHTTPCookieStorage) to CookieMonster.

It is not possible to simply delete all the cookies and re-add
the new version of the cookies, because this can lead to cookie
loss if the application crashes right after deleting all cookies.
For this reason, this CL introduces a new SetAllCookies method
that computes the exact difference between the exiting cookies and
the new cookies, and does only the minimum of operations needed.

Review URL: https://codereview.chromium.org/1000103002

Cr-Commit-Position: refs/heads/master@{#320954}
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 79f1bbf..5633baf 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -234,6 +234,10 @@
   // to the thread you actually want to be notified on.
   void FlushStore(const base::Closure& callback);
 
+  // Replaces all the cookies by |list|. This method does not flush the backend.
+  void SetAllCookiesAsync(const CookieList& list,
+                          const SetCookiesCallback& callback);
+
   // CookieStore implementation.
 
   // Sets the cookies specified by |cookie_list| returned from |url|
@@ -322,6 +326,7 @@
   class GetAllCookiesForURLWithOptionsTask;
   class GetAllCookiesTask;
   class GetCookiesWithOptionsTask;
+  class SetAllCookiesTask;
   class SetCookieWithDetailsTask;
   class SetCookieWithOptionsTask;
   class DeleteSessionCookiesTask;
@@ -350,6 +355,9 @@
   // For FindCookiesForKey.
   FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, ShortLivedSessionCookies);
 
+  // For ComputeCookieDiff.
+  FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, ComputeCookieDiff);
+
   // Internal reasons for deletion, used to populate informative histograms
   // and to provide a public cause for onCookieChange notifications.
   //
@@ -544,6 +552,9 @@
                           const base::Time& creation_time,
                           const CookieOptions& options);
 
+  // Helper function calling SetCanonicalCookie() for all cookies in |list|.
+  bool SetCanonicalCookies(const CookieList& list);
+
   void InternalUpdateCookieAccessTime(CanonicalCookie* cc,
                                       const base::Time& current_time);
 
@@ -608,6 +619,16 @@
   void DoCookieTaskForURL(const scoped_refptr<CookieMonsterTask>& task_item,
                           const GURL& url);
 
+  // Computes the difference between |old_cookies| and |new_cookies|, and writes
+  // the result in |cookies_to_add| and |cookies_to_delete|.
+  // This function has the side effect of changing the order of |old_cookies|
+  // and |new_cookies|. |cookies_to_add| and |cookies_to_delete| must be empty,
+  // and none of the arguments can be null.
+  void ComputeCookieDiff(CookieList* old_cookies,
+                         CookieList* new_cookies,
+                         CookieList* cookies_to_add,
+                         CookieList* cookies_to_delete);
+
   // Run all cookie changed callbacks that are monitoring |cookie|.
   // |removed| is true if the cookie was deleted.
   void RunCallbacks(const CanonicalCookie& cookie, bool removed);