Commit 264807b5 authored by husky@chromium.org's avatar husky@chromium.org

Add CookieStore::DeleteSessionCookiesAsync method.

This is needed by the Android port of Chromium, which has a different
startup and shutdown control flow from other platforms. We also need
to support the Android framework's android.webkit package, which has
a public CookieManager.removeSessionCookie() API.

BUG=None
TEST=CookieMonsterTest


Review URL: http://codereview.chromium.org/9959011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133912 0039d316-1c4b-4281-b951-d872f2087c98
parent 056093a4
...@@ -918,6 +918,32 @@ void CookieMonster::DeleteCookieTask::Run() { ...@@ -918,6 +918,32 @@ void CookieMonster::DeleteCookieTask::Run() {
} }
} }
// Task class for DeleteSessionCookies call.
class CookieMonster::DeleteSessionCookiesTask
: public CookieMonster::CookieMonsterTask {
public:
DeleteSessionCookiesTask(
CookieMonster* cookie_monster,
const CookieMonster::DeleteCallback& callback)
: CookieMonsterTask(cookie_monster),
callback_(callback) { }
virtual void Run() OVERRIDE;
private:
CookieMonster::DeleteCallback callback_;
DISALLOW_COPY_AND_ASSIGN(DeleteSessionCookiesTask);
};
void CookieMonster::DeleteSessionCookiesTask::Run() {
int num_deleted = this->cookie_monster()->DeleteSessionCookies();
if (!callback_.is_null()) {
this->InvokeCallback(base::Bind(&CookieMonster::DeleteCallback::Run,
base::Unretained(&callback_), num_deleted));
}
}
// Asynchronous CookieMonster API // Asynchronous CookieMonster API
void CookieMonster::SetCookieWithDetailsAsync( void CookieMonster::SetCookieWithDetailsAsync(
...@@ -1035,6 +1061,14 @@ void CookieMonster::DeleteCookieAsync(const GURL& url, ...@@ -1035,6 +1061,14 @@ void CookieMonster::DeleteCookieAsync(const GURL& url,
DoCookieTaskForURL(task, url); DoCookieTaskForURL(task, url);
} }
void CookieMonster::DeleteSessionCookiesAsync(
const CookieStore::DeleteCallback& callback) {
scoped_refptr<DeleteSessionCookiesTask> task =
new DeleteSessionCookiesTask(this, callback);
DoCookieTask(task);
}
void CookieMonster::DoCookieTask( void CookieMonster::DoCookieTask(
const scoped_refptr<CookieMonsterTask>& task_item) { const scoped_refptr<CookieMonsterTask>& task_item) {
{ {
...@@ -1390,6 +1424,26 @@ void CookieMonster::DeleteCookie(const GURL& url, ...@@ -1390,6 +1424,26 @@ void CookieMonster::DeleteCookie(const GURL& url,
} }
} }
int CookieMonster::DeleteSessionCookies() {
base::AutoLock autolock(lock_);
int num_deleted = 0;
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
CookieMap::iterator curit = it;
CanonicalCookie* cc = curit->second;
++it;
if (!cc->IsPersistent()) {
InternalDeleteCookie(curit,
true, /*sync_to_store*/
DELETE_COOKIE_EXPIRED);
++num_deleted;
}
}
return num_deleted;
}
CookieMonster* CookieMonster::GetCookieMonster() { CookieMonster* CookieMonster::GetCookieMonster() {
return this; return this;
} }
......
...@@ -246,6 +246,8 @@ class NET_EXPORT CookieMonster : public CookieStore { ...@@ -246,6 +246,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
const base::Time& delete_end, const base::Time& delete_end,
const DeleteCallback& callback) OVERRIDE; const DeleteCallback& callback) OVERRIDE;
virtual void DeleteSessionCookiesAsync(const DeleteCallback&) OVERRIDE;
virtual CookieMonster* GetCookieMonster() OVERRIDE; virtual CookieMonster* GetCookieMonster() OVERRIDE;
// Enables writing session cookies into the cookie database. If this this // Enables writing session cookies into the cookie database. If this this
...@@ -281,6 +283,7 @@ class NET_EXPORT CookieMonster : public CookieStore { ...@@ -281,6 +283,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
class GetCookiesWithInfoTask; class GetCookiesWithInfoTask;
class SetCookieWithDetailsTask; class SetCookieWithDetailsTask;
class SetCookieWithOptionsTask; class SetCookieWithOptionsTask;
class DeleteSessionCookiesTask;
// Testing support. // Testing support.
// For SetCookieWithCreationTime. // For SetCookieWithCreationTime.
...@@ -412,6 +415,8 @@ class NET_EXPORT CookieMonster : public CookieStore { ...@@ -412,6 +415,8 @@ class NET_EXPORT CookieMonster : public CookieStore {
const std::string& cookie_line, const std::string& cookie_line,
const base::Time& creation_time); const base::Time& creation_time);
int DeleteSessionCookies();
// Called by all non-static functions to ensure that the cookies store has // Called by all non-static functions to ensure that the cookies store has
// been initialized. This is not done during creating so it doesn't block // been initialized. This is not done during creating so it doesn't block
// the window showing. // the window showing.
......
...@@ -473,6 +473,16 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> { ...@@ -473,6 +473,16 @@ class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
return callback.result(); return callback.result();
} }
int DeleteSessionCookies(CookieMonster*cm) {
DCHECK(cm);
DeleteCallback callback;
cm->DeleteSessionCookiesAsync(
base::Bind(&DeleteCallback::Run, base::Unretained(&callback)));
RunFor(kTimeout);
EXPECT_TRUE(callback.did_run());
return callback.num_deleted();
}
// Helper for DeleteAllForHost test; repopulates CM with same layout // Helper for DeleteAllForHost test; repopulates CM with same layout
// each time. // each time.
void PopulateCmForDeleteAllForHost(scoped_refptr<CookieMonster> cm) { void PopulateCmForDeleteAllForHost(scoped_refptr<CookieMonster> cm) {
...@@ -757,6 +767,10 @@ ACTION_P(PushCallbackAction, callback_vector) { ...@@ -757,6 +767,10 @@ ACTION_P(PushCallbackAction, callback_vector) {
callback_vector->push(arg1); callback_vector->push(arg1);
} }
ACTION_P2(DeleteSessionCookiesAction, cookie_monster, callback) {
cookie_monster->DeleteSessionCookiesAsync(callback->AsCallback());
}
} // namespace } // namespace
// This test suite verifies the task deferral behaviour of the CookieMonster. // This test suite verifies the task deferral behaviour of the CookieMonster.
...@@ -1096,6 +1110,22 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) { ...@@ -1096,6 +1110,22 @@ TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) {
CompleteLoadingAndWait(); CompleteLoadingAndWait();
} }
TEST_F(DeferredCookieTaskTest, DeferredDeleteSessionCookies) {
MockDeleteCallback delete_callback;
BeginWith(DeleteSessionCookiesAction(
&cookie_monster(), &delete_callback));
WaitForLoadCall();
EXPECT_CALL(delete_callback, Invoke(false)).WillOnce(
DeleteSessionCookiesAction(&cookie_monster(), &delete_callback));
EXPECT_CALL(delete_callback, Invoke(false)).WillOnce(
QuitCurrentMessageLoop());
CompleteLoadingAndWait();
}
// Verify that a series of queued tasks are executed in order upon loading of // Verify that a series of queued tasks are executed in order upon loading of
// the backing store and that new tasks received while the queued tasks are // the backing store and that new tasks received while the queued tasks are
// being dispatched go to the end of the queue. // being dispatched go to the end of the queue.
...@@ -2410,6 +2440,11 @@ class MultiThreadedCookieMonsterTest : public CookieMonsterTest { ...@@ -2410,6 +2440,11 @@ class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
base::Bind(&SetCookieCallback::Run, base::Unretained(callback))); base::Bind(&SetCookieCallback::Run, base::Unretained(callback)));
} }
void DeleteSessionCookiesTask(CookieMonster* cm, DeleteCallback* callback) {
cm->DeleteSessionCookiesAsync(
base::Bind(&DeleteCallback::Run, base::Unretained(callback)));
}
protected: protected:
void RunOnOtherThread(const base::Closure& task) { void RunOnOtherThread(const base::Closure& task) {
other_thread_.Start(); other_thread_.Start();
...@@ -2567,6 +2602,27 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) { ...@@ -2567,6 +2602,27 @@ TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) {
EXPECT_TRUE(callback.result()); EXPECT_TRUE(callback.result());
} }
TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteSessionCookies) {
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
CookieOptions options;
EXPECT_TRUE(SetCookieWithOptions(cm, url_google_, "A=B", options));
EXPECT_TRUE(SetCookieWithOptions(cm, url_google_,
"B=C; expires=Mon, 18-Apr-22 22:50:13 GMT",
options));
EXPECT_EQ(1, DeleteSessionCookies(cm));
EXPECT_EQ(0, DeleteSessionCookies(cm));
EXPECT_TRUE(SetCookieWithOptions(cm, url_google_, "A=B", options));
DeleteCallback callback(&other_thread_);
base::Closure task = base::Bind(
&net::MultiThreadedCookieMonsterTest::DeleteSessionCookiesTask,
base::Unretained(this),
cm, &callback);
RunOnOtherThread(task);
EXPECT_TRUE(callback.did_run());
EXPECT_EQ(1, callback.num_deleted());
}
TEST_F(CookieMonsterTest, ShortLivedSessionCookies) { TEST_F(CookieMonsterTest, ShortLivedSessionCookies) {
scoped_refptr<MockPersistentCookieStore> store( scoped_refptr<MockPersistentCookieStore> store(
new MockPersistentCookieStore); new MockPersistentCookieStore);
......
...@@ -99,6 +99,8 @@ class NET_EXPORT CookieStore : public base::RefCountedThreadSafe<CookieStore> { ...@@ -99,6 +99,8 @@ class NET_EXPORT CookieStore : public base::RefCountedThreadSafe<CookieStore> {
const base::Time& delete_end, const base::Time& delete_end,
const DeleteCallback& callback) = 0; const DeleteCallback& callback) = 0;
virtual void DeleteSessionCookiesAsync(const DeleteCallback&) = 0;
// Returns the underlying CookieMonster. // Returns the underlying CookieMonster.
virtual CookieMonster* GetCookieMonster() = 0; virtual CookieMonster* GetCookieMonster() = 0;
......
...@@ -148,6 +148,10 @@ void DelayedCookieMonster::DeleteAllCreatedBetweenAsync( ...@@ -148,6 +148,10 @@ void DelayedCookieMonster::DeleteAllCreatedBetweenAsync(
ADD_FAILURE(); ADD_FAILURE();
} }
void DelayedCookieMonster::DeleteSessionCookiesAsync(const DeleteCallback&) {
ADD_FAILURE();
}
CookieMonster* DelayedCookieMonster::GetCookieMonster() { CookieMonster* DelayedCookieMonster::GetCookieMonster() {
return cookie_monster_; return cookie_monster_;
} }
......
...@@ -63,6 +63,8 @@ class DelayedCookieMonster : public CookieStore { ...@@ -63,6 +63,8 @@ class DelayedCookieMonster : public CookieStore {
const base::Time& delete_end, const base::Time& delete_end,
const DeleteCallback& callback) OVERRIDE; const DeleteCallback& callback) OVERRIDE;
virtual void DeleteSessionCookiesAsync(const DeleteCallback&) OVERRIDE;
virtual CookieMonster* GetCookieMonster() OVERRIDE; virtual CookieMonster* GetCookieMonster() OVERRIDE;
private: private:
......
...@@ -221,6 +221,9 @@ class MockCookieStore : public net::CookieStore { ...@@ -221,6 +221,9 @@ class MockCookieStore : public net::CookieStore {
const DeleteCallback& callback) { const DeleteCallback& callback) {
ADD_FAILURE(); ADD_FAILURE();
} }
virtual void DeleteSessionCookiesAsync(const DeleteCallback&) {
ADD_FAILURE();
}
virtual net::CookieMonster* GetCookieMonster() { return NULL; } virtual net::CookieMonster* GetCookieMonster() { return NULL; }
......
...@@ -221,6 +221,9 @@ class MockCookieStore : public net::CookieStore { ...@@ -221,6 +221,9 @@ class MockCookieStore : public net::CookieStore {
const DeleteCallback& callback) { const DeleteCallback& callback) {
ADD_FAILURE(); ADD_FAILURE();
} }
virtual void DeleteSessionCookiesAsync(const DeleteCallback&) {
ADD_FAILURE();
}
virtual net::CookieMonster* GetCookieMonster() { return NULL; } virtual net::CookieMonster* GetCookieMonster() { return NULL; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment