1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/automation/automation_util.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <string>
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/values.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/automation/automation_provider.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/automation/automation_provider_json.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/profiles/profile.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/browser_thread.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/browser_render_process_host.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_view_host.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/cookie_monster.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/cookie_store.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GetCookiesOnIOThread(
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url,
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& context_getter,
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent* event,
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string* cookies) {
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *cookies =
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      context_getter->GetURLRequestContext()->cookie_store()->GetCookies(url);
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event->Signal();
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GetCanonicalCookiesOnIOThread(
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url,
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& context_getter,
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent* event,
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::CookieList* cookie_list) {
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *cookie_list =
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      context_getter->GetURLRequestContext()->cookie_store()->
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetCookieMonster()->GetAllCookiesForURL(url);
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event->Signal();
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetCookieOnIOThread(
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url,
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& value,
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& context_getter,
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent* event,
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool* success) {
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *success =
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      context_getter->GetURLRequestContext()->cookie_store()->
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SetCookie(url, value);
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event->Signal();
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetCookieWithDetailsOnIOThread(
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url,
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const net::CookieMonster::CanonicalCookie& cookie,
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& original_domain,
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& context_getter,
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent* event,
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool* success) {
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::CookieMonster* cookie_monster =
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      context_getter->GetURLRequestContext()->cookie_store()->
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetCookieMonster();
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *success = cookie_monster->SetCookieWithDetails(
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url, cookie.Name(), cookie.Value(), original_domain,
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cookie.Path(), cookie.ExpiryDate(), cookie.IsSecure(),
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cookie.IsHttpOnly());
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event->Signal();
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DeleteCookieOnIOThread(
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url,
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& name,
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<net::URLRequestContextGetter>& context_getter,
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent* event) {
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context_getter->GetURLRequestContext()->cookie_store()->
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DeleteCookie(url, name);
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event->Signal();
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace automation_util {
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBrowser* GetBrowserAt(int index) {
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (index < 0 || index >= static_cast<int>(BrowserList::size()))
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return NULL;
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return *(BrowserList::begin() + index);
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTabContents* GetTabContentsAt(int browser_index, int tab_index) {
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_index < 0)
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return NULL;
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Browser* browser = GetBrowserAt(browser_index);
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!browser || tab_index >= browser->tab_count())
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return NULL;
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return browser->GetTabContentsAt(tab_index);
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GetCookies(const GURL& url,
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                TabContents* contents,
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                int* value_size,
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                std::string* value) {
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *value_size = -1;
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (url.is_valid() && contents) {
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Since we may be on the UI thread don't call GetURLRequestContext().
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Get the request context specific to the current TabContents and app.
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const Extension* installed_app = static_cast<BrowserRenderProcessHost*>(
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->render_view_host()->process())->installed_app();
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<net::URLRequestContextGetter> context_getter =
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->profile()->GetRequestContextForPossibleApp(installed_app);
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent event(true /* manual reset */,
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              false /* not initially signaled */);
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CHECK(BrowserThread::PostTask(
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              BrowserThread::IO, FROM_HERE,
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              NewRunnableFunction(&GetCookiesOnIOThread,
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  url, context_getter, &event, value)));
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.Wait();
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    *value_size = static_cast<int>(value->size());
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetCookie(const GURL& url,
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               const std::string& value,
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               TabContents* contents,
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               int* response_value) {
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *response_value = -1;
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (url.is_valid() && contents) {
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Since we may be on the UI thread don't call GetURLRequestContext().
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Get the request context specific to the current TabContents and app.
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const Extension* installed_app = static_cast<BrowserRenderProcessHost*>(
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->render_view_host()->process())->installed_app();
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<net::URLRequestContextGetter> context_getter =
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->profile()->GetRequestContextForPossibleApp(installed_app);
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent event(true /* manual reset */,
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              false /* not initially signaled */);
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool success = false;
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CHECK(BrowserThread::PostTask(
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              BrowserThread::IO, FROM_HERE,
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              NewRunnableFunction(&SetCookieOnIOThread,
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  url, value, context_getter, &event,
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  &success)));
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.Wait();
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (success)
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      *response_value = 1;
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DeleteCookie(const GURL& url,
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  const std::string& cookie_name,
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  TabContents* contents,
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  bool* success) {
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *success = false;
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (url.is_valid() && contents) {
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Since we may be on the UI thread don't call GetURLRequestContext().
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Get the request context specific to the current TabContents and app.
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const Extension* installed_app = static_cast<BrowserRenderProcessHost*>(
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->render_view_host()->process())->installed_app();
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<net::URLRequestContextGetter> context_getter =
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        contents->profile()->GetRequestContextForPossibleApp(installed_app);
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::WaitableEvent event(true /* manual reset */,
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              false /* not initially signaled */);
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CHECK(BrowserThread::PostTask(
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              BrowserThread::IO, FROM_HERE,
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              NewRunnableFunction(&DeleteCookieOnIOThread,
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  url, cookie_name, context_getter, &event)));
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    event.Wait();
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    *success = true;
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GetCookiesJSON(AutomationProvider* provider,
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    DictionaryValue* args,
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    IPC::Message* reply_message) {
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutomationJSONReply reply(provider, reply_message);
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string url;
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!args->GetString("url", &url)) {
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'url' missing or invalid");
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Since we may be on the UI thread don't call GetURLRequestContext().
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> context_getter =
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      provider->profile()->GetRequestContext();
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::CookieList cookie_list;
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent event(true /* manual reset */,
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            false /* not initially signaled */);
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Task* task = NewRunnableFunction(
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &GetCanonicalCookiesOnIOThread,
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GURL(url), context_getter, &event, &cookie_list);
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("Couldn't post task to get the cookies");
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event.Wait();
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ListValue* list = new ListValue();
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < cookie_list.size(); ++i) {
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const net::CookieMonster::CanonicalCookie& cookie = cookie_list[i];
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue* cookie_dict = new DictionaryValue();
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetString("name", cookie.Name());
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetString("value", cookie.Value());
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetString("path", cookie.Path());
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetString("domain", cookie.Domain());
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetBoolean("secure", cookie.IsSecure());
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    cookie_dict->SetBoolean("http_only", cookie.IsHttpOnly());
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (cookie.DoesExpire())
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cookie_dict->SetDouble("expiry", cookie.ExpiryDate().ToDoubleT());
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    list->Append(cookie_dict);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue dict;
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  dict.Set("cookies", list);
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  reply.SendSuccess(&dict);
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid DeleteCookieJSON(AutomationProvider* provider,
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      DictionaryValue* args,
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      IPC::Message* reply_message) {
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutomationJSONReply reply(provider, reply_message);
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string url, name;
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!args->GetString("url", &url)) {
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'url' missing or invalid");
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!args->GetString("name", &name)) {
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'name' missing or invalid");
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Since we may be on the UI thread don't call GetURLRequestContext().
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> context_getter =
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      provider->profile()->GetRequestContext();
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent event(true /* manual reset */,
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            false /* not initially signaled */);
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Task* task = NewRunnableFunction(
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &DeleteCookieOnIOThread,
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GURL(url), name, context_getter, &event);
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("Couldn't post task to delete the cookie");
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event.Wait();
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  reply.SendSuccess(NULL);
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetCookieJSON(AutomationProvider* provider,
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   DictionaryValue* args,
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   IPC::Message* reply_message) {
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AutomationJSONReply reply(provider, reply_message);
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string url;
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!args->GetString("url", &url)) {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'url' missing or invalid");
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue* cookie_dict;
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!args->GetDictionary("cookie", &cookie_dict)) {
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'cookie' missing or invalid");
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string name, value;
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string domain;
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string path = "/";
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool secure = false;
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  double expiry = 0;
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool http_only = false;
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!cookie_dict->GetString("name", &name)) {
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'name' missing or invalid");
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!cookie_dict->GetString("value", &value)) {
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("'value' missing or invalid");
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cookie_dict->HasKey("domain") &&
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !cookie_dict->GetString("domain", &domain)) {
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("optional 'domain' invalid");
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cookie_dict->HasKey("path") &&
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !cookie_dict->GetString("path", &path)) {
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("optional 'path' invalid");
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cookie_dict->HasKey("secure") &&
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !cookie_dict->GetBoolean("secure", &secure)) {
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("optional 'secure' invalid");
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cookie_dict->HasKey("expiry")) {
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int expiry_int;
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (cookie_dict->GetInteger("expiry", &expiry_int)) {
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      expiry = expiry_int;
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (!cookie_dict->GetDouble("expiry", &expiry)) {
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      reply.SendError("optional 'expiry' invalid");
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (cookie_dict->HasKey("http_only") &&
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !cookie_dict->GetBoolean("http_only", &http_only)) {
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("optional 'http_only' invalid");
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<net::CookieMonster::CanonicalCookie> cookie(
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      net::CookieMonster::CanonicalCookie::Create(
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          GURL(url), name, value, domain, path, base::Time(),
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          base::Time::FromDoubleT(expiry), secure, http_only));
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!cookie.get()) {
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("given 'cookie' parameters are invalid");
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Since we may be on the UI thread don't call GetURLRequestContext().
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> context_getter =
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      provider->profile()->GetRequestContext();
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WaitableEvent event(true /* manual reset */,
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            false /* not initially signaled */);
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool success = false;
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Task* task = NewRunnableFunction(
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &SetCookieWithDetailsOnIOThread,
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GURL(url), *cookie.get(), domain, context_getter, &event, &success);
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("Couldn't post task to set the cookie");
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  event.Wait();
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!success) {
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    reply.SendError("Could not set the cookie");
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  reply.SendSuccess(NULL);
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace automation_util
352