15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements the Chrome Extensions Cookies API.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/cookies/cookies_api.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/cookies/cookies_api_constants.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/cookies.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/canonical_cookie.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cookies/cookie_constants.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::api::cookies::Cookie;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::api::cookies::CookieStore;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Get = extensions::api::cookies::Get;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace GetAll = extensions::api::cookies::GetAll;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace GetAllCookieStores = extensions::api::cookies::GetAllCookieStores;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Remove = extensions::api::cookies::Remove;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Set = extensions::api::cookies::Set;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace cookies = api::cookies;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = cookies_api_constants;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ParseUrl(ChromeAsyncExtensionFunction* function,
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu              const std::string& url_string,
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu              GURL* url,
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu              bool check_host_permissions) {
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  *url = GURL(url_string);
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!url->is_valid()) {
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    function->SetError(
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string));
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return false;
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Check against host permissions if needed.
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (check_host_permissions &&
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !function->extension()->permissions_data()->HasHostPermission(*url)) {
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    function->SetError(ErrorUtils::FormatErrorMessage(
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        keys::kNoHostPermissionsError, url->spec()));
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return false;
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return true;
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ParseStoreContext(ChromeAsyncExtensionFunction* function,
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       std::string* store_id,
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       net::URLRequestContextGetter** context) {
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK((context || store_id->empty()));
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Profile* store_profile = NULL;
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!store_id->empty()) {
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    store_profile = cookies_helpers::ChooseProfileFromStoreId(
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        *store_id, function->GetProfile(), function->include_incognito());
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!store_profile) {
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      function->SetError(ErrorUtils::FormatErrorMessage(
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          keys::kInvalidStoreIdError, *store_id));
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return false;
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else {
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // The store ID was not specified; use the current execution context's
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // cookie store by default.
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // GetCurrentBrowser() already takes into account incognito settings.
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Browser* current_browser = function->GetCurrentBrowser();
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!current_browser) {
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      function->SetError(keys::kNoCookieStoreFoundError);
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return false;
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    store_profile = current_browser->profile();
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *store_id = cookies_helpers::GetStoreIdFromProfile(store_profile);
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (context)
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *context = store_profile->GetRequestContext();
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(context);
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return true;
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CookiesEventRouter::CookiesEventRouter(content::BrowserContext* context)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : profile_(Profile::FromBrowserContext(context)) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(registrar_.IsEmpty());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 chrome::NOTIFICATION_COOKIE_CHANGED,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllBrowserContextsAndSources());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesEventRouter::~CookiesEventRouter() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesEventRouter::Observe(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = content::Source<Profile>(source).ptr();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!profile_->IsSameProfile(profile))
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_COOKIE_CHANGED:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CookieChanged(
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          profile,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Details<ChromeCookieDetails>(details).ptr());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesEventRouter::CookieChanged(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeCookieDetails* details) {
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::ListValue> args(new base::ListValue());
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::DictionaryValue* dict = new base::DictionaryValue();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetBoolean(keys::kRemovedKey, details->removed);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Cookie> cookie(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookies_helpers::CreateCookie(*details->cookie,
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          cookies_helpers::GetStoreIdFromProfile(profile)));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->Set(keys::kCookieKey, cookie->ToValue().release());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map the internal cause to an external string.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cause;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (details->cause) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPLICIT:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cause = keys::kExplicitChangeCause;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case net::CookieMonster::Delegate::CHANGE_COOKIE_OVERWRITE:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cause = keys::kOverwriteChangeCause;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPIRED:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cause = keys::kExpiredChangeCause;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case net::CookieMonster::Delegate::CHANGE_COOKIE_EVICTED:
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cause = keys::kEvictedChangeCause;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPIRED_OVERWRITE:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cause = keys::kExpiredOverwriteChangeCause;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict->SetString(keys::kCauseKey, cause);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args->Append(dict);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL cookie_domain =
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookies_helpers::GetURLFromCanonicalCookie(*details->cookie);
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DispatchEvent(profile,
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                cookies::OnChanged::kEventName,
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                args.Pass(),
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                cookie_domain);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CookiesEventRouter::DispatchEvent(content::BrowserContext* context,
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       const std::string& event_name,
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       scoped_ptr<base::ListValue> event_args,
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       GURL& cookie_domain) {
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter* router = context ? extensions::EventRouter::Get(context) : NULL;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!router)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Event> event(new Event(event_name, event_args.Pass()));
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event->restrict_to_browser_context = context;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event->event_url = cookie_domain;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  router->BroadcastEvent(event.Pass());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesGetFunction::CookiesGetFunction() {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesGetFunction::~CookiesGetFunction() {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool CookiesGetFunction::RunAsync() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed_args_ = Get::Params::Create(*args_);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read/validate input parameters.
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseUrl(this, parsed_args_->details.url, &url_, true))
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string store_id =
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.store_id.get() ? *parsed_args_->details.store_id
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           : std::string();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* store_context = NULL;
2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseStoreContext(this, &store_id, &store_context))
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  store_browser_context_ = store_context;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed_args_->details.store_id.get())
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_args_->details.store_id.reset(new std::string(store_id));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  store_browser_context_ = store_context;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetFunction::GetCookieOnIOThread, this));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will finish asynchronously.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetFunction::GetCookieOnIOThread() {
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store =
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      store_browser_context_->GetURLRequestContext()->cookie_store();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookies_helpers::GetCookieListFromStore(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_store, url_,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetFunction::GetCookieCallback, this));
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetFunction::GetCookieCallback(const net::CookieList& cookie_list) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieList::const_iterator it;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the first matching cookie. Relies on the fact that the
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CookieMonster returns them in canonical order (longest path, then
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // earliest creation time).
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->Name() == parsed_args_->details.name) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<Cookie> cookie(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cookies_helpers::CreateCookie(*it, *parsed_args_->details.store_id));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results_ = Get::Results::Create(*cookie);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The cookie doesn't exist; return null.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == cookie_list.end())
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetResult(base::Value::CreateNullValue());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetFunction::RespondOnUIThread, this));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetFunction::RespondOnUIThread() {
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesGetAllFunction::CookiesGetAllFunction() {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesGetAllFunction::~CookiesGetAllFunction() {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool CookiesGetAllFunction::RunAsync() {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed_args_ = GetAll::Params::Create(*args_);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parsed_args_->details.url.get() &&
2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      !ParseUrl(this, *parsed_args_->details.url, &url_, false)) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string store_id =
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.store_id.get() ? *parsed_args_->details.store_id
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           : std::string();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* store_context = NULL;
2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseStoreContext(this, &store_id, &store_context))
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  store_browser_context_ = store_context;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed_args_->details.store_id.get())
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_args_->details.store_id.reset(new std::string(store_id));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetAllFunction::GetAllCookiesOnIOThread, this));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will finish asynchronously.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetAllFunction::GetAllCookiesOnIOThread() {
310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store =
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      store_browser_context_->GetURLRequestContext()->cookie_store();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookies_helpers::GetCookieListFromStore(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_store, url_,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetAllFunction::GetAllCookiesCallback, this));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetAllFunction::GetAllCookiesCallback(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::CookieList& cookie_list) {
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension()) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<linked_ptr<Cookie> > match_vector;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookies_helpers::AppendMatchingCookiesToVector(
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cookie_list, url_, &parsed_args_->details, extension(), &match_vector);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results_ = GetAll::Results::Create(match_vector);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesGetAllFunction::RespondOnUIThread, this));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesGetAllFunction::RespondOnUIThread() {
334effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesSetFunction::CookiesSetFunction() : success_(false) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesSetFunction::~CookiesSetFunction() {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool CookiesSetFunction::RunAsync() {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed_args_ = Set::Params::Create(*args_);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read/validate input parameters.
3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseUrl(this, parsed_args_->details.url, &url_, true))
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string store_id =
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.store_id.get() ? *parsed_args_->details.store_id
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           : std::string();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* store_context = NULL;
3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseStoreContext(this, &store_id, &store_context))
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  store_browser_context_ = store_context;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed_args_->details.store_id.get())
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_args_->details.store_id.reset(new std::string(store_id));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesSetFunction::SetCookieOnIOThread, this));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will finish asynchronously.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesSetFunction::SetCookieOnIOThread() {
372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieMonster* cookie_monster =
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      store_browser_context_->GetURLRequestContext()
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ->cookie_store()
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ->GetCookieMonster();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time expiration_time;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parsed_args_->details.expiration_date.get()) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Time::FromDoubleT converts double time 0 to empty Time object. So we need
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to do special handling here.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expiration_time = (*parsed_args_->details.expiration_date == 0) ?
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Time::UnixEpoch() :
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Time::FromDoubleT(*parsed_args_->details.expiration_date);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_monster->SetCookieWithDetailsAsync(
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_,
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.name.get() ? *parsed_args_->details.name
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       : std::string(),
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.value.get() ? *parsed_args_->details.value
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        : std::string(),
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.domain.get() ? *parsed_args_->details.domain
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         : std::string(),
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.path.get() ? *parsed_args_->details.path
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       : std::string(),
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expiration_time,
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.secure.get() ? *parsed_args_->details.secure.get()
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         : false,
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.http_only.get() ? *parsed_args_->details.http_only
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            : false,
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::COOKIE_PRIORITY_DEFAULT,
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesSetFunction::PullCookie, this));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesSetFunction::PullCookie(bool set_cookie_result) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pull the newly set cookie.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieMonster* cookie_monster =
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      store_browser_context_->GetURLRequestContext()
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ->cookie_store()
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ->GetCookieMonster();
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  success_ = set_cookie_result;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookies_helpers::GetCookieListFromStore(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookie_monster, url_,
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesSetFunction::PullCookieCallback, this));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesSetFunction::PullCookieCallback(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const net::CookieList& cookie_list) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieList::const_iterator it;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the first matching cookie. Relies on the fact that the
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CookieMonster returns them in canonical order (longest path, then
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // earliest creation time).
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string name =
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        parsed_args_->details.name.get() ? *parsed_args_->details.name
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         : std::string();
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->Name() == name) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<Cookie> cookie(
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cookies_helpers::CreateCookie(*it, *parsed_args_->details.store_id));
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results_ = Set::Results::Create(*cookie);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesSetFunction::RespondOnUIThread, this));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesSetFunction::RespondOnUIThread() {
443effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success_) {
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string name =
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        parsed_args_->details.name.get() ? *parsed_args_->details.name
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         : std::string();
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(keys::kCookieSetFailedError, name);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(success_);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesRemoveFunction::CookiesRemoveFunction() {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesRemoveFunction::~CookiesRemoveFunction() {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool CookiesRemoveFunction::RunAsync() {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parsed_args_ = Remove::Params::Create(*args_);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read/validate input parameters.
4645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseUrl(this, parsed_args_->details.url, &url_, true))
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string store_id =
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      parsed_args_->details.store_id.get() ? *parsed_args_->details.store_id
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           : std::string();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* store_context = NULL;
4715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!ParseStoreContext(this, &store_id, &store_context))
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  store_browser_context_ = store_context;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!parsed_args_->details.store_id.get())
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parsed_args_->details.store_id.reset(new std::string(store_id));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass the work off to the IO thread.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesRemoveFunction::RemoveCookieOnIOThread, this));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will return asynchronously.
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesRemoveFunction::RemoveCookieOnIOThread() {
488effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the cookie
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CookieStore* cookie_store =
492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      store_browser_context_->GetURLRequestContext()->cookie_store();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_store->DeleteCookieAsync(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_, parsed_args_->details.name,
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesRemoveFunction::RemoveCookieCallback, this));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesRemoveFunction::RemoveCookieCallback() {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the callback result
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Remove::Results::Details details;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  details.name = parsed_args_->details.name;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  details.url = url_.spec();
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  details.store_id = *parsed_args_->details.store_id;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = Remove::Results::Create(details);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return to UI thread
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rv = BrowserThread::PostTask(
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&CookiesRemoveFunction::RespondOnUIThread, this));
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(rv);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesRemoveFunction::RespondOnUIThread() {
514effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(true);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CookiesGetAllCookieStoresFunction::RunSync() {
5191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Profile* original_profile = GetProfile();
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(original_profile);
521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::ListValue> original_tab_ids(new base::ListValue());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* incognito_profile = NULL;
523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<base::ListValue> incognito_tab_ids;
5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (include_incognito() && GetProfile()->HasOffTheRecordProfile()) {
5251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    incognito_profile = GetProfile()->GetOffTheRecordProfile();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (incognito_profile)
527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      incognito_tab_ids.reset(new base::ListValue());
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(original_profile != incognito_profile);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterate through all browser instances, and for each browser,
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // add its tab IDs to either the regular or incognito tab ID list depending
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whether the browser is regular or incognito.
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Browser* browser = *it;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser->profile() == original_profile) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookies_helpers::AppendToTabIdList(browser, original_tab_ids.get());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (incognito_tab_ids.get() &&
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               browser->profile() == incognito_profile) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cookies_helpers::AppendToTabIdList(browser, incognito_tab_ids.get());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return a list of all cookie stores with at least one open tab.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<linked_ptr<CookieStore> > cookie_stores;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (original_tab_ids->GetSize() > 0) {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_stores.push_back(make_linked_ptr(
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cookies_helpers::CreateCookieStore(
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            original_profile, original_tab_ids.release()).release()));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0 &&
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      incognito_profile) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cookie_stores.push_back(make_linked_ptr(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cookies_helpers::CreateCookieStore(
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            incognito_profile, incognito_tab_ids.release()).release()));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  results_ = GetAllCookieStores::Results::Create(cookie_stores);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CookiesAPI::CookiesAPI(content::BrowserContext* context)
561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : browser_context_(context) {
5620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(browser_context_)
5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ->RegisterObserver(this, cookies::OnChanged::kEventName);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CookiesAPI::~CookiesAPI() {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesAPI::Shutdown() {
5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(browser_context_)->UnregisterObserver(this);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<CookiesAPI> >
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    g_factory = LAZY_INSTANCE_INITIALIZER;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<CookiesAPI>* CookiesAPI::GetFactoryInstance() {
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return g_factory.Pointer();
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CookiesAPI::OnListenerAdded(
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::EventListenerInfo& details) {
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cookies_event_router_.reset(new CookiesEventRouter(browser_context_));
5840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EventRouter::Get(browser_context_)->UnregisterObserver(this);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
588