Skip to content

Commit 794f5d5

Browse files
committed
Cookie API: cookies.onChanged.addListener and removeListener
1 parent 3edde1f commit 794f5d5

File tree

6 files changed

+173
-9
lines changed

6 files changed

+173
-9
lines changed

src/api/window/window.cc

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
#include "base/values.h"
2424
#include "base/strings/stringprintf.h"
2525
#include "base/strings/utf_string_conversions.h"
26+
#include "chrome/browser/chrome_notification_types.h"
2627
#include "content/nw/src/api/dispatcher_host.h"
2728
#include "content/nw/src/api/menu/menu.h"
2829
#include "content/nw/src/browser/native_window.h"
2930
#include "content/nw/src/nw_shell.h"
3031
#include "content/nw/src/shell_browser_context.h"
3132
#include "content/public/browser/browser_thread.h"
33+
#include "content/public/browser/notification_service.h"
3234
#include "content/public/browser/render_view_host.h"
35+
#include "content/public/common/url_constants.h"
3336
#include "net/cookies/canonical_cookie.h"
3437
#include "net/cookies/cookie_constants.h"
3538
#include "net/cookies/cookie_monster.h"
@@ -38,9 +41,33 @@
3841
#include "url/gurl.h"
3942

4043
using content::BrowserThread;
44+
using content::ShellBrowserContext;
4145

4246
namespace {
4347

48+
const char kCauseKey[] = "cause";
49+
const char kCookieKey[] = "cookie";
50+
const char kDomainKey[] = "domain";
51+
const char kIdKey[] = "id";
52+
const char kRemovedKey[] = "removed";
53+
const char kTabIdsKey[] = "tabIds";
54+
55+
// Cause Constants
56+
const char kEvictedChangeCause[] = "evicted";
57+
const char kExpiredChangeCause[] = "expired";
58+
const char kExpiredOverwriteChangeCause[] = "expired_overwrite";
59+
const char kExplicitChangeCause[] = "explicit";
60+
const char kOverwriteChangeCause[] = "overwrite";
61+
62+
GURL GetURLFromCanonicalCookie(const net::CanonicalCookie& cookie) {
63+
const std::string& domain_key = cookie.Domain();
64+
const std::string scheme =
65+
cookie.IsSecure() ? "https" : "http";
66+
const std::string host =
67+
domain_key.find('.') != 0 ? domain_key : domain_key.substr(1);
68+
return GURL(scheme + content::kStandardSchemeSeparator + host + "/");
69+
}
70+
4471
void GetCookieListFromStore(
4572
net::CookieStore* cookie_store, const GURL& url,
4673
const net::CookieMonster::GetCookieListCallback& callback) {
@@ -143,7 +170,10 @@ Window::Window(int id,
143170
DVLOG(1) << "Window::Window(" << id << ")";
144171
// Set ID for Shell
145172
shell_->set_id(id);
146-
173+
CHECK(registrar_.IsEmpty());
174+
registrar_.Add(this,
175+
chrome::NOTIFICATION_COOKIE_CHANGED,
176+
content::NotificationService::AllBrowserContextsAndSources());
147177
}
148178

149179
Window::~Window() {
@@ -512,4 +542,70 @@ void Window::PullCookieCallback(CookieAPIContext* api_context,
512542
DCHECK(rv);
513543
}
514544

545+
void Window::Observe(
546+
int type,
547+
const content::NotificationSource& source,
548+
const content::NotificationDetails& details) {
549+
550+
ShellBrowserContext* browser_context =
551+
content::Source<ShellBrowserContext>(source).ptr();
552+
553+
switch (type) {
554+
case chrome::NOTIFICATION_COOKIE_CHANGED:
555+
CookieChanged(
556+
browser_context,
557+
content::Details<ChromeCookieDetails>(details).ptr());
558+
break;
559+
560+
default:
561+
NOTREACHED();
562+
}
563+
}
564+
565+
void Window::CookieChanged(
566+
ShellBrowserContext* browser_context,
567+
ChromeCookieDetails* details) {
568+
scoped_ptr<base::ListValue> args(new base::ListValue());
569+
base::DictionaryValue* dict = new base::DictionaryValue();
570+
dict->SetBoolean(kRemovedKey, details->removed);
571+
dict->Set(kCookieKey, PopulateCookieObject(*details->cookie));
572+
573+
// Map the internal cause to an external string.
574+
std::string cause;
575+
switch (details->cause) {
576+
case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPLICIT:
577+
cause = kExplicitChangeCause;
578+
break;
579+
580+
case net::CookieMonster::Delegate::CHANGE_COOKIE_OVERWRITE:
581+
cause = kOverwriteChangeCause;
582+
break;
583+
584+
case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPIRED:
585+
cause = kExpiredChangeCause;
586+
break;
587+
588+
case net::CookieMonster::Delegate::CHANGE_COOKIE_EVICTED:
589+
cause = kEvictedChangeCause;
590+
break;
591+
592+
case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPIRED_OVERWRITE:
593+
cause = kExpiredOverwriteChangeCause;
594+
break;
595+
596+
default:
597+
NOTREACHED();
598+
}
599+
dict->SetString(kCauseKey, cause);
600+
601+
args->Append(dict);
602+
603+
GURL cookie_domain =
604+
GetURLFromCanonicalCookie(*details->cookie);
605+
606+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
607+
dispatcher_host()->SendEvent(this, "__nw_cookie_changed", *args);
608+
609+
}
610+
515611
} // namespace api

src/api/window/window.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323

2424
#include "base/compiler_specific.h"
2525
#include "base/values.h"
26+
#include "chrome/browser/net/chrome_cookie_notification_details.h"
2627
#include "content/nw/src/api/base/base.h"
28+
#include "content/public/browser/notification_observer.h"
29+
#include "content/public/browser/notification_registrar.h"
2730
#include "content/public/browser/render_process_host.h"
2831
#include "net/cookies/canonical_cookie.h"
2932
#include "net/url_request/url_request_context_getter.h"
@@ -32,6 +35,7 @@
3235

3336
namespace content {
3437
class Shell;
38+
class ShellBrowserContext;
3539
}
3640

3741
namespace api {
@@ -50,7 +54,7 @@ class CookieAPIContext : public base::RefCountedThreadSafe<CookieAPIContext> {
5054
};
5155

5256

53-
class Window : public Base {
57+
class Window : public Base, public content::NotificationObserver {
5458
public:
5559
Window(int id,
5660
DispatcherHost* dispatcher_host,
@@ -77,9 +81,19 @@ class Window : public Base {
7781
const net::CookieList& cookie_list);
7882
void PullCookie(CookieAPIContext* api_context, bool set_cookie_result);
7983
void SetCookieOnIOThread(CookieAPIContext* api_context);
80-
private:
84+
85+
private:
86+
// content::NotificationObserver implementation.
87+
virtual void Observe(int type,
88+
const content::NotificationSource& source,
89+
const content::NotificationDetails& details) OVERRIDE;
90+
91+
// Handler for the COOKIE_CHANGED event. The method takes the details of such
92+
// an event and constructs a suitable JSON formatted extension event from it.
93+
void CookieChanged(content::ShellBrowserContext*, ChromeCookieDetails* details);
8194

8295
content::Shell* shell_;
96+
content::NotificationRegistrar registrar_;
8397

8498
DISALLOW_COPY_AND_ASSIGN(Window);
8599
};

src/api/window_bindings.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ function Window(routing_id, nobind) {
6161
});
6262
}
6363
CallObjectMethod(that, 'CookieSet', [ this.req_id, details ]);
64+
},
65+
onChanged : {
66+
addListener : function(cb) {
67+
that.on('__nw_cookie_changed', cb);
68+
},
69+
removeListener : function(cb) {
70+
that.removeListener('__nw_cookie_changed', cb);
71+
}
6472
}
6573
}
6674
}

src/net/shell_url_request_context_getter.cc

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
#include "base/strings/string_split.h"
2525
#include "base/strings/string_util.h"
2626
#include "base/threading/worker_pool.h"
27+
#include "chrome/browser/chrome_notification_types.h"
28+
#include "chrome/browser/net/chrome_cookie_notification_details.h"
2729
#include "content/public/browser/browser_thread.h"
30+
#include "content/public/browser/notification_service.h"
2831
#include "content/public/common/url_constants.h"
2932
#include "content/nw/src/net/shell_network_delegate.h"
3033
#include "content/public/browser/cookie_store_factory.h"
@@ -75,6 +78,43 @@ void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory,
7578
protocol_handlers->clear();
7679
}
7780

81+
// ----------------------------------------------------------------------------
82+
// CookieMonster::Delegate implementation
83+
// ----------------------------------------------------------------------------
84+
class NWCookieMonsterDelegate : public net::CookieMonster::Delegate {
85+
public:
86+
explicit NWCookieMonsterDelegate(ShellBrowserContext* browser_context)
87+
: browser_context_(browser_context) {
88+
}
89+
90+
// net::CookieMonster::Delegate implementation.
91+
virtual void OnCookieChanged(
92+
const net::CanonicalCookie& cookie,
93+
bool removed,
94+
net::CookieMonster::Delegate::ChangeCause cause) OVERRIDE {
95+
BrowserThread::PostTask(
96+
BrowserThread::UI, FROM_HERE,
97+
base::Bind(&NWCookieMonsterDelegate::OnCookieChangedAsyncHelper,
98+
this, cookie, removed, cause));
99+
}
100+
101+
private:
102+
virtual ~NWCookieMonsterDelegate() {}
103+
104+
void OnCookieChangedAsyncHelper(
105+
const net::CanonicalCookie& cookie,
106+
bool removed,
107+
net::CookieMonster::Delegate::ChangeCause cause) {
108+
ChromeCookieDetails cookie_details(&cookie, removed, cause);
109+
content::NotificationService::current()->Notify(
110+
chrome::NOTIFICATION_COOKIE_CHANGED,
111+
content::Source<ShellBrowserContext>(browser_context_),
112+
content::Details<ChromeCookieDetails>(&cookie_details));
113+
}
114+
115+
ShellBrowserContext* browser_context_;
116+
};
117+
78118
} // namespace
79119

80120

@@ -84,12 +124,14 @@ ShellURLRequestContextGetter::ShellURLRequestContextGetter(
84124
const FilePath& root_path,
85125
MessageLoop* io_loop,
86126
MessageLoop* file_loop,
87-
ProtocolHandlerMap* protocol_handlers)
127+
ProtocolHandlerMap* protocol_handlers,
128+
ShellBrowserContext* browser_context)
88129
: ignore_certificate_errors_(ignore_certificate_errors),
89130
data_path_(data_path),
90131
root_path_(root_path),
91132
io_loop_(io_loop),
92-
file_loop_(file_loop) {
133+
file_loop_(file_loop),
134+
browser_context_(browser_context) {
93135
// Must first be created on the UI thread.
94136
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
95137

@@ -126,7 +168,7 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() {
126168
cookie_path,
127169
false,
128170
NULL,
129-
NULL);
171+
new NWCookieMonsterDelegate(browser_context_));
130172
cookie_store->GetCookieMonster()->SetPersistSessionCookies(true);
131173
storage_->set_cookie_store(cookie_store);
132174

src/net/shell_url_request_context_getter.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,18 @@ class MessageLoop;
4343

4444
namespace content {
4545

46-
class ShellURLRequestContextGetter : public net::URLRequestContextGetter {
46+
class ShellBrowserContext;
47+
48+
class ShellURLRequestContextGetter : public net::URLRequestContextGetter {
4749
public:
4850
ShellURLRequestContextGetter(
4951
bool ignore_certificate_errors,
5052
const base::FilePath& data_path,
5153
const base::FilePath& root_path,
5254
base::MessageLoop* io_loop,
5355
base::MessageLoop* file_loop,
54-
ProtocolHandlerMap* protocol_handlers);
56+
ProtocolHandlerMap* protocol_handlers,
57+
ShellBrowserContext*);
5558

5659
// net::URLRequestContextGetter implementation.
5760
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
@@ -75,6 +78,7 @@ class ShellURLRequestContextGetter : public net::URLRequestContextGetter {
7578
scoped_ptr<net::URLRequestContextStorage> storage_;
7679
scoped_ptr<net::URLRequestContext> url_request_context_;
7780
ProtocolHandlerMap protocol_handlers_;
81+
ShellBrowserContext* browser_context_;
7882

7983
DISALLOW_COPY_AND_ASSIGN(ShellURLRequestContextGetter);
8084
};

src/shell_browser_context.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ net::URLRequestContextGetter* ShellBrowserContext::CreateRequestContext(
161161
package_->path(),
162162
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
163163
BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
164-
protocol_handlers);
164+
protocol_handlers, this);
165165
resource_context_->set_url_request_context_getter(url_request_getter_.get());
166166
return url_request_getter_.get();
167167
}

0 commit comments

Comments
 (0)