diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 18:13:40 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 18:13:40 +0000 |
commit | b5c6e3061b38fc9936063c4b95a6fdb36dcd494d (patch) | |
tree | c33e9e39fe93750f0947b046f686df44d5ca5182 /chrome | |
parent | 042c368e489772c0ff89f25beb396a948659a268 (diff) | |
download | chromium_src-b5c6e3061b38fc9936063c4b95a6fdb36dcd494d.zip chromium_src-b5c6e3061b38fc9936063c4b95a6fdb36dcd494d.tar.gz chromium_src-b5c6e3061b38fc9936063c4b95a6fdb36dcd494d.tar.bz2 |
Add support for HTML5 databases to the cookie tree model.
BUG=34633
TEST=create local databases, open cookie tree view from prefs.
Review URL: http://codereview.chromium.org/596009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38635 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
26 files changed, 1411 insertions, 252 deletions
diff --git a/chrome/browser/browsing_data_database_helper.cc b/chrome/browser/browsing_data_database_helper.cc new file mode 100644 index 0000000..addbf93 --- /dev/null +++ b/chrome/browser/browsing_data_database_helper.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browsing_data_database_helper.h" + +#include "base/file_util.h" +#include "base/message_loop.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/profile.h" +#include "third_party/WebKit/WebKit/chromium/public/WebCString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#include "webkit/database/database_tracker.h" +#include "webkit/glue/webkit_glue.h" + +BrowsingDataDatabaseHelper::BrowsingDataDatabaseHelper(Profile* profile) + : profile_(profile), + completion_callback_(NULL), + is_fetching_(false) { + DCHECK(profile_); +} + +BrowsingDataDatabaseHelper::~BrowsingDataDatabaseHelper() { +} + +void BrowsingDataDatabaseHelper::StartFetching( + Callback1<const std::vector<DatabaseInfo>& >::Type* callback) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(!is_fetching_); + DCHECK(callback); + is_fetching_ = true; + database_info_.clear(); + completion_callback_.reset(callback); + ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, NewRunnableMethod( + this, &BrowsingDataDatabaseHelper::FetchDatabaseInfoInFileThread)); +} + +void BrowsingDataDatabaseHelper::CancelNotification() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + completion_callback_.reset(NULL); +} + +void BrowsingDataDatabaseHelper::DeleteDatabase(const std::string& origin, + const std::string& name) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,NewRunnableMethod( + this, &BrowsingDataDatabaseHelper::DeleteDatabaseInFileThread, origin, + name)); +} + +void BrowsingDataDatabaseHelper::FetchDatabaseInfoInFileThread() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + std::vector<webkit_database::OriginInfo> origins_info; + scoped_refptr<webkit_database::DatabaseTracker> tracker = + profile_->GetDatabaseTracker(); + if (tracker.get() && tracker->GetAllOriginsInfo(&origins_info)) { + for (std::vector<webkit_database::OriginInfo>::const_iterator ori = + origins_info.begin(); ori != origins_info.end(); ++ori) { + scoped_ptr<WebKit::WebSecurityOrigin> web_security_origin( + WebKit::WebSecurityOrigin::createFromDatabaseIdentifier( + ori->GetOrigin())); + std::vector<string16> databases; + ori->GetAllDatabaseNames(&databases); + for (std::vector<string16>::const_iterator db = databases.begin(); + db != databases.end(); ++db) { + FilePath file_path = tracker->GetFullDBFilePath(ori->GetOrigin(), *db); + file_util::FileInfo file_info; + if (file_util::GetFileInfo(file_path, &file_info)) { + database_info_.push_back(DatabaseInfo( + web_security_origin->host().utf8(), + UTF16ToUTF8(*db), + UTF16ToUTF8(ori->GetOrigin()), + UTF16ToUTF8(ori->GetDatabaseDescription(*db)), + file_info.size, + file_info.last_modified)); + } + } + } + } + + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, NewRunnableMethod( + this, &BrowsingDataDatabaseHelper::NotifyInUIThread)); +} + +void BrowsingDataDatabaseHelper::NotifyInUIThread() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(is_fetching_); + // Note: completion_callback_ mutates only in the UI thread, so it's safe to + // test it here. + if (completion_callback_ != NULL) + completion_callback_->Run(database_info_); + is_fetching_ = false; + database_info_.clear(); +} + +void BrowsingDataDatabaseHelper::DeleteDatabaseInFileThread( + const std::string& origin, + const std::string& name) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + // TODO(jochen): delete the given database. +} diff --git a/chrome/browser/browsing_data_database_helper.h b/chrome/browser/browsing_data_database_helper.h new file mode 100644 index 0000000..0b2440c --- /dev/null +++ b/chrome/browser/browsing_data_database_helper.h @@ -0,0 +1,103 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BROWSING_DATA_DATABASE_HELPER_H_ +#define CHROME_BROWSER_BROWSING_DATA_DATABASE_HELPER_H_ + +#include <string> +#include <vector> + +#include "base/scoped_ptr.h" +#include "base/task.h" + +class Profile; + +// This class fetches database information in the FILE thread, and notifies the +// UI thread upon completion. +// A client of this class need to call StartFetching from the UI thread to +// initiate the flow, and it'll be notified by the callback in its UI +// thread at some later point. +// The client must call CancelNotification() if it's destroyed before the +// callback is notified. +class BrowsingDataDatabaseHelper + : public base::RefCountedThreadSafe<BrowsingDataDatabaseHelper> { + public: + // Contains detailed information about a web database. + struct DatabaseInfo { + DatabaseInfo() {} + DatabaseInfo(const std::string& host, + const std::string& database_name, + const std::string& origin_identifier, + const std::string& description, + int64 size, + base::Time last_modified) + : host(host), + database_name(database_name), + origin_identifier(origin_identifier), + description(description), + size(size), + last_modified(last_modified) { + } + + std::string host; + std::string database_name; + std::string origin_identifier; + std::string description; + int64 size; + base::Time last_modified; + }; + + explicit BrowsingDataDatabaseHelper(Profile* profile); + + // Starts the fetching process, which will notify its completion via + // callback. + // This must be called only in the UI thread. + virtual void StartFetching( + Callback1<const std::vector<DatabaseInfo>& >::Type* callback); + + // Cancels the notification callback (i.e., the window that created it no + // longer exists). + // This must be called only in the UI thread. + virtual void CancelNotification(); + + // Requests a single database to be deleted in the FILE thread. This must be + // called in the UI thread. + virtual void DeleteDatabase(const std::string& origin, + const std::string& name); + + private: + friend class base::RefCountedThreadSafe<BrowsingDataDatabaseHelper>; + friend class MockBrowsingDataDatabaseHelper; + + virtual ~BrowsingDataDatabaseHelper(); + + // Enumerates all databases. This must be called in the FILE thread. + void FetchDatabaseInfoInFileThread(); + + // Notifies the completion callback. This must be called in the UI thread. + void NotifyInUIThread(); + + // Delete a single database file. This must be called in the FILE thread. + void DeleteDatabaseInFileThread(const std::string& origin, + const std::string& name); + + Profile* profile_; + + // This only mutates on the UI thread. + scoped_ptr<Callback1<const std::vector<DatabaseInfo>& >::Type > + completion_callback_; + + // Indicates whether or not we're currently fetching information: + // it's true when StartFetching() is called in the UI thread, and it's reset + // after we notify the callback in the UI thread. + // This only mutates on the UI thread. + bool is_fetching_; + + // This only mutates in the FILE thread. + std::vector<DatabaseInfo> database_info_; + + DISALLOW_COPY_AND_ASSIGN(BrowsingDataDatabaseHelper); +}; + +#endif // CHROME_BROWSER_BROWSING_DATA_DATABASE_HELPER_H_ diff --git a/chrome/browser/browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data_local_storage_helper.cc index 5bb42c8..6a31cf9 100644 --- a/chrome/browser/browsing_data_local_storage_helper.cc +++ b/chrome/browser/browsing_data_local_storage_helper.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -57,16 +57,6 @@ void BrowsingDataLocalStorageHelper::DeleteLocalStorageFile( file_path)); } -void BrowsingDataLocalStorageHelper::DeleteAllLocalStorageFiles() { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - ChromeThread::PostTask( - ChromeThread::WEBKIT, FROM_HERE, - NewRunnableMethod( - this, - &BrowsingDataLocalStorageHelper:: - DeleteAllLocalStorageFilesInWebKitThread)); -} - void BrowsingDataLocalStorageHelper::FetchLocalStorageInfoInWebKitThread() { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); file_util::FileEnumerator file_enumerator( @@ -119,10 +109,3 @@ void BrowsingDataLocalStorageHelper::DeleteLocalStorageFileInWebKitThread( profile_->GetWebKitContext()->dom_storage_context()->DeleteLocalStorageFile( file_path); } - -void - BrowsingDataLocalStorageHelper::DeleteAllLocalStorageFilesInWebKitThread() { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::WEBKIT)); - profile_->GetWebKitContext()->dom_storage_context() - ->DeleteAllLocalStorageFiles(); -} diff --git a/chrome/browser/browsing_data_local_storage_helper.h b/chrome/browser/browsing_data_local_storage_helper.h index 5b971e4..af423b9 100644 --- a/chrome/browser/browsing_data_local_storage_helper.h +++ b/chrome/browser/browsing_data_local_storage_helper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -68,8 +68,6 @@ class BrowsingDataLocalStorageHelper virtual void CancelNotification(); // Requests a single local storage file to be deleted in the WEBKIT thread. virtual void DeleteLocalStorageFile(const FilePath& file_path); - // Requests all local storage files to be deleted in the WEBKIT thread. - virtual void DeleteAllLocalStorageFiles(); private: friend class base::RefCountedThreadSafe<BrowsingDataLocalStorageHelper>; @@ -82,8 +80,6 @@ class BrowsingDataLocalStorageHelper void NotifyInUIThread(); // Delete a single local storage file in the WEBKIT thread. void DeleteLocalStorageFileInWebKitThread(const FilePath& file_path); - // Delete all local storage files in the WEBKIT thread. - void DeleteAllLocalStorageFilesInWebKitThread(); Profile* profile_; // This only mutates on the UI thread. diff --git a/chrome/browser/browsing_data_local_storage_helper_unittest.cc b/chrome/browser/browsing_data_local_storage_helper_unittest.cc index f36b724..1664903 100644 --- a/chrome/browser/browsing_data_local_storage_helper_unittest.cc +++ b/chrome/browser/browsing_data_local_storage_helper_unittest.cc @@ -145,26 +145,3 @@ IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, DeleteSingleFile) { } ASSERT_EQ(2, num_files); } - -IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, DeleteAllFiles) { - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper( - new BrowsingDataLocalStorageHelper(&testing_profile_)); - CreateLocalStorageFilesForTest(); - local_storage_helper->DeleteAllLocalStorageFiles(); - scoped_refptr<WaitForWebKitThread> wait_for_webkit_thread( - new WaitForWebKitThread); - wait_for_webkit_thread->QuitUiMessageLoopAfterWebKitThreadNotified(); - // Blocks until WaitForWebKitThread is notified. - ui_test_utils::RunMessageLoop(); - // Ensure the alls files but the one without local storage extension have been - // deleted. - file_util::FileEnumerator file_enumerator( - GetLocalStoragePathForTestingProfile(), - false, - file_util::FileEnumerator::FILES); - for (FilePath file_path = file_enumerator.Next(); - !file_path.empty(); - file_path = file_enumerator.Next()) { - ASSERT_TRUE(FilePath(kTestFileInvalid) == file_path.BaseName()); - } -} diff --git a/chrome/browser/cocoa/cookies_window_controller.h b/chrome/browser/cocoa/cookies_window_controller.h index 9c354bd..c2beb5e 100644 --- a/chrome/browser/cocoa/cookies_window_controller.h +++ b/chrome/browser/cocoa/cookies_window_controller.h @@ -100,6 +100,7 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver { IBOutlet NSView* localStorageInfo_; Profile* profile_; // weak + BrowsingDataDatabaseHelper* databaseHelper_; // weak BrowsingDataLocalStorageHelper* storageHelper_; // weak } @property (assign, nonatomic) BOOL removeButtonEnabled; @@ -107,6 +108,7 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver { // Designated initializer. Profile cannot be NULL. - (id)initWithProfile:(Profile*)profile + databaseHelper:(BrowsingDataDatabaseHelper*)databaseHelper storageHelper:(BrowsingDataLocalStorageHelper*)storageHelper; // Shows the cookies window as a modal sheet attached to |window|. diff --git a/chrome/browser/cocoa/cookies_window_controller.mm b/chrome/browser/cocoa/cookies_window_controller.mm index b760c41..b61145a 100644 --- a/chrome/browser/cocoa/cookies_window_controller.mm +++ b/chrome/browser/cocoa/cookies_window_controller.mm @@ -163,12 +163,14 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { @synthesize treeController = treeController_; - (id)initWithProfile:(Profile*)profile + databaseHelper:(BrowsingDataDatabaseHelper*)databaseHelper storageHelper:(BrowsingDataLocalStorageHelper*)storageHelper { DCHECK(profile); NSString* nibpath = [mac_util::MainAppBundle() pathForResource:@"Cookies" ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibpath owner:self])) { profile_ = profile; + databaseHelper_ = databaseHelper; storageHelper_ = storageHelper; [self loadTreeModelFromProfile]; @@ -248,7 +250,7 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { - (IBAction)deleteAllCookies:(id)sender { // Preemptively delete all cookies in the Cocoa model. modelObserver_->InvalidateCocoaModel(); - treeModel_->DeleteAllCookies(); + treeModel_->DeleteAllStoredObjects(); } - (IBAction)closeSheet:(id)sender { @@ -376,7 +378,8 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { // to rebuild after the user clears browsing data. Because the models get // clobbered, we rebuild the icon cache for safety (though they do not change). - (void)loadTreeModelFromProfile { - treeModel_.reset(new CookiesTreeModel(profile_, storageHelper_)); + treeModel_.reset(new CookiesTreeModel(profile_, databaseHelper_, + storageHelper_)); modelObserver_.reset(new CookiesTreeModelObserverBridge(self)); treeModel_->SetObserver(modelObserver_.get()); diff --git a/chrome/browser/cocoa/cookies_window_controller_unittest.mm b/chrome/browser/cocoa/cookies_window_controller_unittest.mm index 036259a..70b90ca 100644 --- a/chrome/browser/cocoa/cookies_window_controller_unittest.mm +++ b/chrome/browser/cocoa/cookies_window_controller_unittest.mm @@ -12,6 +12,7 @@ #include "chrome/browser/cocoa/clear_browsing_data_controller.h" #import "chrome/browser/cocoa/cookies_window_controller.h" #include "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/mock_browsing_data_database_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/browser/cookies_tree_model.h" @@ -53,9 +54,11 @@ class CookiesWindowControllerTest : public CocoaTest { CocoaTest::SetUp(); TestingProfile* profile = browser_helper_.profile(); profile->CreateRequestContext(); + database_helper_ = new MockBrowsingDataDatabaseHelper(profile); local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_] ); } @@ -78,6 +81,7 @@ class CookiesWindowControllerTest : public CocoaTest { // Need an IO thread to not leak from TestingProfile::CreateRequestContext(). ChromeThread io_thread_; scoped_nsobject<CookiesWindowController> controller_; + MockBrowsingDataDatabaseHelper* database_helper_; MockBrowsingDataLocalStorageHelper* local_storage_helper_; }; @@ -130,7 +134,8 @@ TEST_F(CookiesWindowControllerTest, FindCocoaNodeRecursive) { TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeCookie) { net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); cm->SetCookie(GURL("http://foo.com"), "A=B"); - CookiesTreeModel model(browser_helper_.profile(), local_storage_helper_); + CookiesTreeModel model(browser_helper_.profile(), database_helper_, + local_storage_helper_); // Root --> foo.com --> Cookies --> A. Create node for 'A'. TreeModelNode* node = model.GetRoot()->GetChild(0)->GetChild(0)->GetChild(0); @@ -151,7 +156,8 @@ TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeCookie) { TEST_F(CookiesWindowControllerTest, CocoaNodeFromTreeNodeRecursive) { net::CookieMonster* cm = browser_helper_.profile()->GetCookieMonster(); cm->SetCookie(GURL("http://foo.com"), "A=B"); - CookiesTreeModel model(browser_helper_.profile(), local_storage_helper_); + CookiesTreeModel model(browser_helper_.profile(), database_helper_, + local_storage_helper_); // Root --> foo.com --> Cookies --> A. Create node for 'foo.com'. CookieTreeNode* node = model.GetRoot()->GetChild(0); @@ -194,6 +200,7 @@ TEST_F(CookiesWindowControllerTest, TreeNodesAdded) { controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); // Root --> foo.com --> Cookies. @@ -236,6 +243,7 @@ TEST_F(CookiesWindowControllerTest, TreeNodesRemoved) { controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); // Root --> foo.com --> Cookies. @@ -267,6 +275,7 @@ TEST_F(CookiesWindowControllerTest, TreeNodeChildrenReordered) { controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); // Root --> foo.com --> Cookies. @@ -313,6 +322,7 @@ TEST_F(CookiesWindowControllerTest, TreeNodeChanged) { controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); CookiesTreeModel* model = [controller_ treeModel]; @@ -346,6 +356,7 @@ TEST_F(CookiesWindowControllerTest, TestDeleteCookie) { // scoper, we'd get a double-free. CookiesWindowController* controller = [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]; [controller attachSheetTo:test_window()]; NSTreeController* treeController = [controller treeController]; @@ -377,6 +388,7 @@ TEST_F(CookiesWindowControllerTest, TestDidExpandItem) { controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); // Root --> foo.com. @@ -442,10 +454,12 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) { // This will clean itself up when we call |-closeSheet:|. If we reset the // scoper, we'd get a double-free. + database_helper_ = new MockBrowsingDataDatabaseHelper(profile); local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); local_storage_helper_->AddLocalStorageSamples(); CookiesWindowController* controller = [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]; local_storage_helper_->Notify(); [controller attachSheetTo:test_window()]; @@ -520,6 +534,7 @@ TEST_F(CookiesWindowControllerTest, UpdateFilter) controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); // Make sure we registered all five cookies. @@ -564,10 +579,12 @@ TEST_F(CookiesWindowControllerTest, CreateLocalStorageNodes) { net::CookieMonster* cm = profile->GetCookieMonster(); cm->SetCookie(GURL("http://google.com"), "A=B"); cm->SetCookie(GURL("http://dev.chromium.org"), "C=D"); + database_helper_ = new MockBrowsingDataDatabaseHelper(profile); local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile); local_storage_helper_->AddLocalStorageSamples(); controller_.reset( [[CookiesWindowController alloc] initWithProfile:profile + databaseHelper:database_helper_ storageHelper:local_storage_helper_]); local_storage_helper_->Notify(); diff --git a/chrome/browser/cocoa/preferences_window_controller.mm b/chrome/browser/cocoa/preferences_window_controller.mm index 3ec7520..56e369f 100644 --- a/chrome/browser/cocoa/preferences_window_controller.mm +++ b/chrome/browser/cocoa/preferences_window_controller.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -1313,10 +1313,13 @@ const int kDisabledIndex = 1; // Shows the cookies controller. - (IBAction)showCookies:(id)sender { // The controller will clean itself up. + BrowsingDataDatabaseHelper* databaseHelper = + new BrowsingDataDatabaseHelper(profile_); BrowsingDataLocalStorageHelper* storageHelper = new BrowsingDataLocalStorageHelper(profile_); CookiesWindowController* controller = [[CookiesWindowController alloc] initWithProfile:profile_ + databaseHelper:databaseHelper storageHelper:storageHelper]; [controller attachSheetTo:[self window]]; } diff --git a/chrome/browser/cookies_tree_model.cc b/chrome/browser/cookies_tree_model.cc index aa699bf..b6b56b8 100644 --- a/chrome/browser/cookies_tree_model.cc +++ b/chrome/browser/cookies_tree_model.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -52,7 +52,17 @@ CookieTreeCookieNode::CookieTreeCookieNode( } void CookieTreeCookieNode::DeleteStoredObjects() { - GetModel()->DeleteCookie(*cookie_); + // notify CookieMonster that we should delete this cookie + // Since we are running on the UI thread don't call GetURLRequestContext(). + net::CookieMonster* monster = GetModel()->profile_-> + GetRequestContext()->GetCookieStore()->GetCookieMonster(); + // We have stored a copy of all the cookies in the model, and our model is + // never re-calculated. Thus, we just need to delete the nodes from our + // model, and tell CookieMonster to delete the cookies. We can keep the + // vector storing the cookies in-tact and not delete from there (that would + // invalidate our pointers), and the fact that it contains semi out-of-date + // data is not problematic as we don't re-build the model based on that. + monster->DeleteCookie(cookie_->first, cookie_->second, true); } namespace { @@ -115,19 +125,31 @@ class OriginNodeComparator { } // namespace /////////////////////////////////////////////////////////////////////////////// +// CookieTreeDatabaseNode, public: + +CookieTreeDatabaseNode::CookieTreeDatabaseNode( + BrowsingDataDatabaseHelper::DatabaseInfo* database_info) + : CookieTreeNode(UTF8ToWide(database_info->database_name)), + database_info_(database_info) { +} + +void CookieTreeDatabaseNode::DeleteStoredObjects() { + GetModel()->database_helper_->DeleteDatabase( + database_info_->origin_identifier, database_info_->database_name); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeLocalStorageNode, public: CookieTreeLocalStorageNode::CookieTreeLocalStorageNode( BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info) - : CookieTreeNode(UTF8ToWide( - !local_storage_info->origin.empty() ? - local_storage_info->origin : - local_storage_info->database_identifier)), + : CookieTreeNode(UTF8ToWide(local_storage_info->origin)), local_storage_info_(local_storage_info) { } void CookieTreeLocalStorageNode::DeleteStoredObjects() { - GetModel()->DeleteLocalStorage(local_storage_info_->file_path); + GetModel()->local_storage_helper_->DeleteLocalStorageFile( + local_storage_info_->file_path); } /////////////////////////////////////////////////////////////////////////////// @@ -172,13 +194,29 @@ CookieTreeCookiesNode* CookieTreeOriginNode::GetOrCreateCookiesNode() { return retval; } +CookieTreeDatabasesNode* + CookieTreeOriginNode::GetOrCreateDatabasesNode() { + if (databases_child_) + return databases_child_; + // Need to make a Database node, add it to the tree, and return it. + CookieTreeDatabasesNode* retval = new CookieTreeDatabasesNode; + GetModel()->Add(this, cookies_child_ ? 1 : 0, retval); + databases_child_ = retval; + return retval; +} + CookieTreeLocalStoragesNode* CookieTreeOriginNode::GetOrCreateLocalStoragesNode() { if (local_storages_child_) return local_storages_child_; - // need to make a LocalStorages node, add it to the tree, and return it + // Need to make a LocalStorages node, add it to the tree, and return it. CookieTreeLocalStoragesNode* retval = new CookieTreeLocalStoragesNode; - GetModel()->Add(this, cookies_child_ ? 1 : 0, retval); + int index = 0; + if (cookies_child_) + index++; + if (databases_child_) + index++; + GetModel()->Add(this, index, retval); local_storages_child_ = retval; return retval; } @@ -201,6 +239,25 @@ void CookieTreeCookiesNode::AddCookieNode( } /////////////////////////////////////////////////////////////////////////////// +// CookieTreeDatabasesNode, public: + +CookieTreeDatabasesNode::CookieTreeDatabasesNode() + : CookieTreeNode(l10n_util::GetString(IDS_COOKIES_WEB_DATABASES)) { +} + +void CookieTreeDatabasesNode::AddDatabaseNode( + CookieTreeDatabaseNode* new_child) { + std::vector<CookieTreeNode*>::iterator database_iterator = + lower_bound(children().begin(), + children().end(), + new_child, + CookieTreeDatabaseNode::CookieNodeComparator()); + GetModel()->Add(this, + (database_iterator - children().begin()), + new_child); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeLocalStoragesNode, public: CookieTreeLocalStoragesNode::CookieTreeLocalStoragesNode() @@ -232,6 +289,19 @@ bool CookieTreeCookieNode::CookieNodeComparator::operator() ( } /////////////////////////////////////////////////////////////////////////////// +// CookieTreeDatabaseNode, private + +bool CookieTreeDatabaseNode::CookieNodeComparator::operator() ( + const CookieTreeNode* lhs, const CookieTreeNode* rhs) { + const CookieTreeDatabaseNode* left = + static_cast<const CookieTreeDatabaseNode*>(lhs); + const CookieTreeDatabaseNode* right = + static_cast<const CookieTreeDatabaseNode*>(rhs); + return (left->database_info_->database_name < + right->database_info_->database_name); +} + +/////////////////////////////////////////////////////////////////////////////// // CookieTreeLocalStorageNode, private bool CookieTreeLocalStorageNode::CookieNodeComparator::operator() ( @@ -249,18 +319,24 @@ bool CookieTreeLocalStorageNode::CookieNodeComparator::operator() ( CookiesTreeModel::CookiesTreeModel( Profile* profile, + BrowsingDataDatabaseHelper* database_helper, BrowsingDataLocalStorageHelper* local_storage_helper) : ALLOW_THIS_IN_INITIALIZER_LIST(TreeNodeModel<CookieTreeNode>( new CookieTreeRootNode(this))), profile_(profile), + database_helper_(database_helper), local_storage_helper_(local_storage_helper) { LoadCookies(); + DCHECK(database_helper_); + database_helper_->StartFetching(NewCallback( + this, &CookiesTreeModel::OnDatabaseModelInfoLoaded)); DCHECK(local_storage_helper_); local_storage_helper_->StartFetching(NewCallback( this, &CookiesTreeModel::OnStorageModelInfoLoaded)); } CookiesTreeModel::~CookiesTreeModel() { + database_helper_->CancelNotification(); local_storage_helper_->CancelNotification(); } @@ -289,6 +365,8 @@ int CookiesTreeModel::GetIconIndex(TreeModelNode* node) { case CookieTreeNode::DetailedInfo::TYPE_COOKIE: return COOKIE; break; + case CookieTreeNode::DetailedInfo::TYPE_DATABASE: + // TODO(jochen): add an icon for databases. case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: // TODO(bulach): add an icon for local storage. default: @@ -297,7 +375,7 @@ int CookiesTreeModel::GetIconIndex(TreeModelNode* node) { } void CookiesTreeModel::LoadCookies() { - LoadCookiesWithFilter(L""); + LoadCookiesWithFilter(std::wstring()); } void CookiesTreeModel::LoadCookiesWithFilter(const std::wstring& filter) { @@ -324,22 +402,7 @@ void CookiesTreeModel::LoadCookiesWithFilter(const std::wstring& filter) { } } -void CookiesTreeModel::DeleteCookie( - const net::CookieMonster::CookieListPair& cookie) { - // notify CookieMonster that we should delete this cookie - // Since we are running on the UI thread don't call GetURLRequestContext(). - net::CookieMonster* monster = - profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(); - // We have stored a copy of all the cookies in the model, and our model is - // never re-calculated. Thus, we just need to delete the nodes from our - // model, and tell CookieMonster to delete the cookies. We can keep the - // vector storing the cookies in-tact and not delete from there (that would - // invalidate our pointers), and the fact that it contains semi out-of-date - // data is not problematic as we don't re-build the model based on that. - monster->DeleteCookie(cookie.first, cookie.second, true); -} - -void CookiesTreeModel::DeleteAllCookies() { +void CookiesTreeModel::DeleteAllStoredObjects() { CookieTreeNode* root = GetRoot(); root->DeleteStoredObjects(); int num_children = root->GetChildCount(); @@ -356,28 +419,47 @@ void CookiesTreeModel::DeleteCookieNode(CookieTreeNode* cookie_node) { delete Remove(parent_node, cookie_node_index); } -void CookiesTreeModel::DeleteLocalStorage(const FilePath& file_path) { - local_storage_helper_->DeleteLocalStorageFile(file_path); -} - -void CookiesTreeModel::DeleteAllLocalStorage() { - local_storage_helper_->DeleteAllLocalStorageFiles(); -} - void CookiesTreeModel::UpdateSearchResults(const std::wstring& filter) { CookieTreeNode* root = GetRoot(); int num_children = root->GetChildCount(); for (int i = num_children - 1; i >= 0; --i) delete Remove(root, i); LoadCookiesWithFilter(filter); + PopulateDatabaseInfoWithFilter(filter); PopulateLocalStorageInfoWithFilter(filter); NotifyObserverTreeNodeChanged(root); } +void CookiesTreeModel::OnDatabaseModelInfoLoaded( + const DatabaseInfoList& database_info) { + database_info_list_ = database_info; + PopulateDatabaseInfoWithFilter(std::wstring()); +} + +void CookiesTreeModel::PopulateDatabaseInfoWithFilter( + const std::wstring& filter) { + CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(GetRoot()); + for (DatabaseInfoList::iterator database_info = database_info_list_.begin(); + database_info != database_info_list_.end(); + ++database_info) { + std::string origin = database_info->host; + if (!filter.size() || + (UTF8ToWide(origin).find(filter) != std::wstring::npos)) { + CookieTreeOriginNode* origin_node = root->GetOrCreateOriginNode( + UTF8ToWide(database_info->host)); + CookieTreeDatabasesNode* databases_node = + origin_node->GetOrCreateDatabasesNode(); + databases_node->AddDatabaseNode( + new CookieTreeDatabaseNode(&(*database_info))); + } + } + NotifyObserverTreeNodeChanged(root); +} + void CookiesTreeModel::OnStorageModelInfoLoaded( const LocalStorageInfoList& local_storage_info) { local_storage_info_list_ = local_storage_info; - PopulateLocalStorageInfoWithFilter(L""); + PopulateLocalStorageInfoWithFilter(std::wstring()); } void CookiesTreeModel::PopulateLocalStorageInfoWithFilter( @@ -387,10 +469,7 @@ void CookiesTreeModel::PopulateLocalStorageInfoWithFilter( local_storage_info_list_.begin(); local_storage_info != local_storage_info_list_.end(); ++local_storage_info) { - std::string origin = - !local_storage_info->host.empty() ? - local_storage_info->host : - local_storage_info->database_identifier; + std::string origin = local_storage_info->host; if (!filter.size() || (UTF8ToWide(origin).find(filter) != std::wstring::npos)) { CookieTreeOriginNode* origin_node = root->GetOrCreateOriginNode( diff --git a/chrome/browser/cookies_tree_model.h b/chrome/browser/cookies_tree_model.h index 8a4bd60..1d1d8bb 100644 --- a/chrome/browser/cookies_tree_model.h +++ b/chrome/browser/cookies_tree_model.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,22 +10,25 @@ #include "app/tree_node_model.h" #include "base/scoped_ptr.h" +#include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "net/base/cookie_monster.h" class CookiesTreeModel; class CookieTreeLocalStorageNode; class CookieTreeLocalStoragesNode; +class CookieTreeDatabaseNode; +class CookieTreeDatabasesNode; class CookieTreeCookieNode; class CookieTreeCookiesNode; class CookieTreeOriginNode; class Profile; // CookieTreeNode ------------------------------------------------------------- -// The base node type in the Cookies + Local Storage options view, from which -// all other types are derived. Specialized from TreeNode in that it has a -// notion of deleting objects stored in the profile, and being able to have -// its children do the same. +// The base node type in the Cookies, Databases, and Local Storage options +// view, from which all other types are derived. Specialized from TreeNode in +// that it has a notion of deleting objects stored in the profile, and being +// able to have its children do the same. class CookieTreeNode : public TreeNode<CookieTreeNode> { public: // Used to pull out information for the InfoView (the details display below @@ -37,18 +40,24 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> { TYPE_ORIGIN, // This is used for CookieTreeOriginNode nodes. TYPE_COOKIES, // This is used for CookieTreeCookiesNode nodes. TYPE_COOKIE, // This is used for CookieTreeCookieNode nodes. + TYPE_DATABASES, // This is used for CookieTreeDatabasesNode. + TYPE_DATABASE, // This is used for CookieTreeDatabaseNode. TYPE_LOCAL_STORAGES, // This is used for CookieTreeLocalStoragesNode. TYPE_LOCAL_STORAGE, // This is used for CookieTreeLocalStorageNode. }; DetailedInfo(const std::wstring& origin, NodeType node_type, const net::CookieMonster::CookieListPair* cookie, + const BrowsingDataDatabaseHelper::DatabaseInfo* database_info, const BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info) : origin(origin), node_type(node_type), cookie(cookie), + database_info(database_info), local_storage_info(local_storage_info) { + if (node_type == TYPE_DATABASE) + DCHECK(database_info); if (node_type == TYPE_LOCAL_STORAGE) DCHECK(local_storage_info); } @@ -56,6 +65,7 @@ class CookieTreeNode : public TreeNode<CookieTreeNode> { std::wstring origin; NodeType node_type; const net::CookieMonster::CookieListPair* cookie; + const BrowsingDataDatabaseHelper::DatabaseInfo* database_info; const BrowsingDataLocalStorageHelper::LocalStorageInfo* local_storage_info; }; @@ -91,7 +101,8 @@ class CookieTreeRootNode : public CookieTreeNode { // CookieTreeNode methods: virtual CookiesTreeModel* GetModel() const { return model_; } virtual DetailedInfo GetDetailedInfo() const { - return DetailedInfo(std::wstring(), DetailedInfo::TYPE_ROOT, NULL, NULL); + return DetailedInfo(std::wstring(), DetailedInfo::TYPE_ROOT, NULL, NULL, + NULL); } private: @@ -104,17 +115,21 @@ class CookieTreeRootNode : public CookieTreeNode { class CookieTreeOriginNode : public CookieTreeNode { public: explicit CookieTreeOriginNode(const std::wstring& origin) - : CookieTreeNode(origin), cookies_child_(NULL), + : CookieTreeNode(origin), + cookies_child_(NULL), + databases_child_(NULL), local_storages_child_(NULL) {} virtual ~CookieTreeOriginNode() {} // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { - return DetailedInfo(GetTitle(), DetailedInfo::TYPE_ORIGIN, NULL, NULL); + return DetailedInfo(GetTitle(), DetailedInfo::TYPE_ORIGIN, NULL, NULL, + NULL); } // CookieTreeOriginNode methods: CookieTreeCookiesNode* GetOrCreateCookiesNode(); + CookieTreeDatabasesNode* GetOrCreateDatabasesNode(); CookieTreeLocalStoragesNode* GetOrCreateLocalStoragesNode(); private: @@ -126,6 +141,7 @@ class CookieTreeOriginNode : public CookieTreeNode { // DATABASES etc node seems less preferable than storing an extra pointer per // origin. CookieTreeCookiesNode* cookies_child_; + CookieTreeDatabasesNode* databases_child_; CookieTreeLocalStoragesNode* local_storages_child_; DISALLOW_COPY_AND_ASSIGN(CookieTreeOriginNode); @@ -140,7 +156,7 @@ class CookieTreeCookiesNode : public CookieTreeNode { // CookieTreeNode methods: virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetTitle(), DetailedInfo::TYPE_COOKIES, - NULL, NULL); + NULL, NULL, NULL); } // CookieTreeCookiesNode methods: @@ -163,7 +179,7 @@ class CookieTreeCookieNode : public CookieTreeNode { virtual void DeleteStoredObjects(); virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetParent()->GetTitle(), - DetailedInfo::TYPE_COOKIE, cookie_, NULL); + DetailedInfo::TYPE_COOKIE, cookie_, NULL, NULL); } private: @@ -181,6 +197,59 @@ class CookieTreeCookieNode : public CookieTreeNode { DISALLOW_COPY_AND_ASSIGN(CookieTreeCookieNode); }; +// CookieTreeDatabasesNode ----------------------------------------------------- +class CookieTreeDatabasesNode : public CookieTreeNode { + public: + CookieTreeDatabasesNode(); + virtual ~CookieTreeDatabasesNode() {} + + // CookieTreeNode methods: + virtual DetailedInfo GetDetailedInfo() const { + return DetailedInfo(GetParent()->GetTitle(), + DetailedInfo::TYPE_DATABASES, + NULL, NULL, NULL); + } + + // CookieTreeDatabases methods: + void AddDatabaseNode(CookieTreeDatabaseNode* child); + + private: + DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabasesNode); +}; + +class CookieTreeDatabaseNode : public CookieTreeNode { + public: + friend class CookieTreeDatabasesNode; + + // Does not take ownership of database_info, and database_info should remain + // valid at least as long as the CookieTreeDatabaseNode is valid. + explicit CookieTreeDatabaseNode( + BrowsingDataDatabaseHelper::DatabaseInfo* database_info); + virtual ~CookieTreeDatabaseNode() {} + + // CookieTreeStorageNode methods: + virtual void DeleteStoredObjects(); + virtual DetailedInfo GetDetailedInfo() const { + return DetailedInfo(GetParent()->GetParent()->GetTitle(), + DetailedInfo::TYPE_DATABASE, NULL, database_info_, + NULL); + } + + private: + // Comparator functor, takes CookieTreeNode so that we can use it in + // lower_bound using children()'s iterators, which are CookieTreeNode*. + class CookieNodeComparator { + public: + bool operator() (const CookieTreeNode* lhs, const CookieTreeNode* rhs); + }; + + // database_info_ is not owned by the node, and is expected to remain + // valid as long as the CookieTreeDatabaseNode is valid. + BrowsingDataDatabaseHelper::DatabaseInfo* database_info_; + + DISALLOW_COPY_AND_ASSIGN(CookieTreeDatabaseNode); +}; + // CookieTreeLocalStoragesNode ------------------------------------------------- class CookieTreeLocalStoragesNode : public CookieTreeNode { public: @@ -191,8 +260,7 @@ class CookieTreeLocalStoragesNode : public CookieTreeNode { virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetTitle(), DetailedInfo::TYPE_LOCAL_STORAGES, - NULL, - NULL); + NULL, NULL, NULL); } // CookieTreeStoragesNode methods: @@ -216,7 +284,7 @@ class CookieTreeLocalStorageNode : public CookieTreeNode { virtual void DeleteStoredObjects(); virtual DetailedInfo GetDetailedInfo() const { return DetailedInfo(GetParent()->GetParent()->GetTitle(), - DetailedInfo::TYPE_LOCAL_STORAGE, NULL, + DetailedInfo::TYPE_LOCAL_STORAGE, NULL, NULL, local_storage_info_); } @@ -239,6 +307,7 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { public: CookiesTreeModel( Profile* profile, + BrowsingDataDatabaseHelper* browsing_data_database_helper, BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); virtual ~CookiesTreeModel(); @@ -253,11 +322,8 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { virtual int GetIconIndex(TreeModelNode* node); // CookiesTreeModel methods: - void DeleteCookie(const net::CookieMonster::CookieListPair& cookie); - void DeleteAllCookies(); + void DeleteAllStoredObjects(); void DeleteCookieNode(CookieTreeNode* cookie_node); - void DeleteLocalStorage(const FilePath& file_path); - void DeleteAllLocalStorage(); // Filter the origins to only display matched results. void UpdateSearchResults(const std::wstring& filter); @@ -266,27 +332,41 @@ class CookiesTreeModel : public TreeNodeModel<CookieTreeNode> { enum CookieIconIndex { ORIGIN = 0, COOKIE = 1, - LOCAL_STORAGE = 2, + DATABASE = 2, + LOCAL_STORAGE = 3, }; typedef net::CookieMonster::CookieList CookieList; typedef std::vector<net::CookieMonster::CookieListPair*> CookiePtrList; + typedef std::vector<BrowsingDataDatabaseHelper::DatabaseInfo> + DatabaseInfoList; typedef std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> LocalStorageInfoList; void LoadCookies(); void LoadCookiesWithFilter(const std::wstring& filter); + void OnDatabaseModelInfoLoaded(const DatabaseInfoList& database_info); + void OnStorageModelInfoLoaded(const LocalStorageInfoList& local_storage_info); + void PopulateDatabaseInfoWithFilter(const std::wstring& filter); + void PopulateLocalStorageInfoWithFilter(const std::wstring& filter); // The profile from which this model sources cookies. Profile* profile_; CookieList all_cookies_; + scoped_refptr<BrowsingDataDatabaseHelper> database_helper_; + DatabaseInfoList database_info_list_; + scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_; LocalStorageInfoList local_storage_info_list_; + friend class CookieTreeCookieNode; + friend class CookieTreeDatabaseNode; + friend class CookieTreeLocalStorageNode; + DISALLOW_COPY_AND_ASSIGN(CookiesTreeModel); }; diff --git a/chrome/browser/cookies_tree_model_unittest.cc b/chrome/browser/cookies_tree_model_unittest.cc index 9a055a5..48d280b 100644 --- a/chrome/browser/cookies_tree_model_unittest.cc +++ b/chrome/browser/cookies_tree_model_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,6 +7,7 @@ #include <string> #include "app/l10n_util.h" +#include "chrome/browser/mock_browsing_data_database_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/test/testing_profile.h" @@ -27,7 +28,9 @@ class CookiesTreeModelTest : public testing::Test { virtual void SetUp() { profile_.reset(new TestingProfile()); profile_->CreateRequestContext(); - mock_browsing_data_helper_ = + mock_browsing_data_database_helper_ = + new MockBrowsingDataDatabaseHelper(profile_.get()); + mock_browsing_data_local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile_.get()); } @@ -37,15 +40,20 @@ class CookiesTreeModelTest : public testing::Test { monster->SetCookie(GURL("http://foo2"), "B=1"); monster->SetCookie(GURL("http://foo3"), "C=1"); CookiesTreeModel* cookies_model = new CookiesTreeModel( - profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + profile_.get(), mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); { - SCOPED_TRACE("Initial State 3 cookies, 2 local storages"); - // 16 because there's the root, then foo1 -> cookies -> a, + SCOPED_TRACE("Initial State 3 cookies, 2 databases, 2 local storages"); + // 22 because there's the root, then foo1 -> cookies -> a, // foo2 -> cookies -> b, foo3 -> cookies -> c, + // dbhost1 -> database -> db1, dbhost2 -> database -> db2, // host1 -> localstorage -> origin1, host2 -> localstorage -> origin2. - EXPECT_EQ(16, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(22, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model)); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(cookies_model)); } return cookies_model; @@ -79,6 +87,8 @@ class CookiesTreeModelTest : public testing::Test { switch (node_type) { case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE: return node->GetDetailedInfo().local_storage_info->origin + ","; + case CookieTreeNode::DetailedInfo::TYPE_DATABASE: + return node->GetDetailedInfo().database_info->database_name + ","; case CookieTreeNode::DetailedInfo::TYPE_COOKIE: return node->GetDetailedInfo().cookie->second.Name() + ","; default: @@ -94,6 +104,11 @@ class CookiesTreeModelTest : public testing::Test { return GetNodesOfChildren(node, CookieTreeNode::DetailedInfo::TYPE_COOKIE); } + std::string GetDatabasesOfChildren(const CookieTreeNode* node) { + return GetNodesOfChildren(node, + CookieTreeNode::DetailedInfo::TYPE_DATABASE); + } + std::string GetLocalStoragesOfChildren(const CookieTreeNode* node) { return GetNodesOfChildren(node, CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE); @@ -117,6 +132,11 @@ class CookiesTreeModelTest : public testing::Test { CookieTreeNode::DetailedInfo::TYPE_COOKIE); } + std::string GetDisplayedDatabases(CookiesTreeModel* cookies_model) { + return GetDisplayedNodes(cookies_model, + CookieTreeNode::DetailedInfo::TYPE_DATABASE); + } + std::string GetDisplayedLocalStorages(CookiesTreeModel* cookies_model) { return GetDisplayedNodes(cookies_model, CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE); @@ -136,7 +156,10 @@ class CookiesTreeModelTest : public testing::Test { ChromeThread io_thread_; scoped_ptr<TestingProfile> profile_; - scoped_refptr<MockBrowsingDataLocalStorageHelper> mock_browsing_data_helper_; + scoped_refptr<MockBrowsingDataDatabaseHelper> + mock_browsing_data_database_helper_; + scoped_refptr<MockBrowsingDataLocalStorageHelper> + mock_browsing_data_local_storage_helper_; }; TEST_F(CookiesTreeModelTest, RemoveAll) { @@ -149,12 +172,16 @@ TEST_F(CookiesTreeModelTest, RemoveAll) { SCOPED_TRACE("Before removing"); EXPECT_EQ(GetMonsterCookies(monster), GetDisplayedCookies(cookies_model.get())); + EXPECT_EQ("db1,db2", + GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(cookies_model.get())); } - cookies_model->DeleteAllCookies(); - cookies_model->DeleteAllLocalStorage(); + mock_browsing_data_database_helper_->Reset(); + mock_browsing_data_local_storage_helper_->Reset(); + + cookies_model->DeleteAllStoredObjects(); { SCOPED_TRACE("After removing"); @@ -163,7 +190,8 @@ TEST_F(CookiesTreeModelTest, RemoveAll) { EXPECT_EQ(std::string(""), GetMonsterCookies(monster)); EXPECT_EQ(GetMonsterCookies(monster), GetDisplayedCookies(cookies_model.get())); - EXPECT_TRUE(mock_browsing_data_helper_->delete_all_files_called_); + EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted()); } } @@ -177,17 +205,30 @@ TEST_F(CookiesTreeModelTest, Remove) { SCOPED_TRACE("First cookie origin removed"); EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); - EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(cookies_model.get())); - EXPECT_EQ(13, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("origin1,origin2", + GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ(19, cookies_model->GetRoot()->GetTotalNodeCount()); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(2)); { + SCOPED_TRACE("First database origin removed"); + EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ(16, cookies_model->GetRoot()->GetTotalNodeCount()); + } + + DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)); + { SCOPED_TRACE("First local storage origin removed"); EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("origin2", GetDisplayedLocalStorages(cookies_model.get())); - EXPECT_EQ(10, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(13, cookies_model->GetRoot()->GetTotalNodeCount()); } } @@ -201,22 +242,36 @@ TEST_F(CookiesTreeModelTest, RemoveCookiesNode) { SCOPED_TRACE("First origin removed"); EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); - // 14 because in this case, the origin remains, although the COOKIES + // 20 because in this case, the origin remains, although the COOKIES // node beneath it has been deleted. So, we have // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c + // dbhost1 -> database -> db1, dbhost2 -> database -> db2, // host1 -> localstorage -> origin1, host2 -> localstorage -> origin2. - EXPECT_EQ(14, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(20, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(cookies_model.get())); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0)); { + SCOPED_TRACE("First database removed"); + EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("origin1,origin2", + GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ(18, cookies_model->GetRoot()->GetTotalNodeCount()); + } + + DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0)); + { SCOPED_TRACE("First origin removed"); EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("origin2", GetDisplayedLocalStorages(cookies_model.get())); - EXPECT_EQ(12, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(16, cookies_model->GetRoot()->GetTotalNodeCount()); } } @@ -230,20 +285,36 @@ TEST_F(CookiesTreeModelTest, RemoveCookieNode) { SCOPED_TRACE("Second origin COOKIES node removed"); EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); - // 14 because in this case, the origin remains, although the COOKIES + EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("origin1,origin2", + GetDisplayedLocalStorages(cookies_model.get())); + // 20 because in this case, the origin remains, although the COOKIES // node beneath it has been deleted. So, we have // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c + // dbhost1 -> database -> db1, dbhost2 -> database -> db2, // host1 -> localstorage -> origin1, host2 -> localstorage -> origin2. - EXPECT_EQ(14, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(20, cookies_model->GetRoot()->GetTotalNodeCount()); } DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0)); { + SCOPED_TRACE("First database removed"); + EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); + EXPECT_EQ("origin1,origin2", + GetDisplayedLocalStorages(cookies_model.get())); + EXPECT_EQ(18, cookies_model->GetRoot()->GetTotalNodeCount()); + } + + DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0)); + { SCOPED_TRACE("First origin removed"); EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str()); + EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get())); EXPECT_EQ("origin2", GetDisplayedLocalStorages(cookies_model.get())); - EXPECT_EQ(12, cookies_model->GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(16, cookies_model->GetRoot()->GetTotalNodeCount()); } } @@ -253,19 +324,24 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) { monster->SetCookie(GURL("http://foo2"), "B=1"); monster->SetCookie(GURL("http://foo3"), "C=1"); monster->SetCookie(GURL("http://foo3"), "D=1"); - CookiesTreeModel cookies_model( - profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesTreeModel cookies_model(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); { - SCOPED_TRACE("Initial State 4 cookies, 2 local storages"); - // 17 because there's the root, then foo1 -> cookies -> a, + SCOPED_TRACE("Initial State 4 cookies, 2 databases, 2 local storages"); + // 23 because there's the root, then foo1 -> cookies -> a, // foo2 -> cookies -> b, foo3 -> cookies -> c,d + // dbhost1 -> database -> db1, dbhost2 -> database -> db2, // host1 -> localstorage -> origin1, host2 -> localstorage -> origin2. - EXPECT_EQ(17, cookies_model.GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(23, cookies_model.GetRoot()->GetTotalNodeCount()); EXPECT_STREQ("A,B,C,D", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,B,C,D", GetDisplayedCookies(&cookies_model).c_str()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(&cookies_model)); } DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2)); @@ -273,7 +349,9 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) { SCOPED_TRACE("Third origin removed"); EXPECT_STREQ("A,B", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,B", GetDisplayedCookies(&cookies_model).c_str()); - EXPECT_EQ(13, cookies_model.GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); + EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(&cookies_model)); + EXPECT_EQ(19, cookies_model.GetRoot()->GetTotalNodeCount()); } } @@ -284,18 +362,24 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) { monster->SetCookie(GURL("http://foo3"), "C=1"); monster->SetCookie(GURL("http://foo3"), "D=1"); monster->SetCookie(GURL("http://foo3"), "E=1"); - CookiesTreeModel cookies_model(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesTreeModel cookies_model(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); { - SCOPED_TRACE("Initial State 5 cookies, 2 local storages"); - // 17 because there's the root, then foo1 -> cookies -> a, + SCOPED_TRACE("Initial State 5 cookies, 2 databases, 2 local storages"); + // 24 because there's the root, then foo1 -> cookies -> a, // foo2 -> cookies -> b, foo3 -> cookies -> c,d,e + // dbhost1 -> database -> db1, dbhost2 -> database -> db2, // host1 -> localstorage -> origin1, host2 -> localstorage -> origin2. - EXPECT_EQ(18, cookies_model.GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(24, cookies_model.GetRoot()->GetTotalNodeCount()); EXPECT_STREQ("A,B,C,D,E", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,B,C,D,E", GetDisplayedCookies(&cookies_model).c_str()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(&cookies_model)); } DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2)->GetChild(0)-> @@ -304,7 +388,8 @@ TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) { SCOPED_TRACE("Middle cookie in third origin removed"); EXPECT_STREQ("A,B,C,E", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("A,B,C,E", GetDisplayedCookies(&cookies_model).c_str()); - EXPECT_EQ(17, cookies_model.GetRoot()->GetTotalNodeCount()); + EXPECT_EQ(23, cookies_model.GetRoot()->GetTotalNodeCount()); + EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model)); EXPECT_EQ("origin1,origin2", GetDisplayedLocalStorages(&cookies_model)); } } @@ -316,7 +401,9 @@ TEST_F(CookiesTreeModelTest, RemoveSecondOrigin) { monster->SetCookie(GURL("http://foo3"), "C=1"); monster->SetCookie(GURL("http://foo3"), "D=1"); monster->SetCookie(GURL("http://foo3"), "E=1"); - CookiesTreeModel cookies_model(profile_.get(), mock_browsing_data_helper_); + CookiesTreeModel cookies_model(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); { SCOPED_TRACE("Initial State 5 cookies"); // 11 because there's the root, then foo1 -> cookies -> a, @@ -347,8 +434,9 @@ TEST_F(CookiesTreeModelTest, OriginOrdering) { monster->SetCookie(GURL("http://foo3.com"), "G=1"); monster->SetCookie(GURL("http://foo4.com"), "H=1"); - CookiesTreeModel cookies_model( - profile_.get(), new MockBrowsingDataLocalStorageHelper(profile_.get())); + CookiesTreeModel cookies_model(profile_.get(), + new MockBrowsingDataDatabaseHelper(profile_.get()), + new MockBrowsingDataLocalStorageHelper(profile_.get())); { SCOPED_TRACE("Initial State 8 cookies"); diff --git a/chrome/browser/gtk/options/advanced_contents_gtk.cc b/chrome/browser/gtk/options/advanced_contents_gtk.cc index aaa8c7e..84cb54c 100644 --- a/chrome/browser/gtk/options/advanced_contents_gtk.cc +++ b/chrome/browser/gtk/options/advanced_contents_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -773,6 +773,8 @@ void PrivacySection::OnShowCookiesButtonClicked( GtkButton *button, PrivacySection* privacy_section) { privacy_section->UserMetricsRecordAction("Options_ShowCookies", NULL); CookiesView::Show(privacy_section->profile(), + new BrowsingDataDatabaseHelper( + privacy_section->profile()), new BrowsingDataLocalStorageHelper( privacy_section->profile())); } diff --git a/chrome/browser/gtk/options/cookies_view.cc b/chrome/browser/gtk/options/cookies_view.cc index 25abfa3..86a1d7e 100644 --- a/chrome/browser/gtk/options/cookies_view.cc +++ b/chrome/browser/gtk/options/cookies_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -59,23 +59,29 @@ CookiesView::~CookiesView() { // static void CookiesView::Show( Profile* profile, + BrowsingDataDatabaseHelper* browsing_data_database_helper, BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper) { DCHECK(profile); + DCHECK(browsing_data_database_helper); DCHECK(browsing_data_local_storage_helper); // If there's already an existing editor window, activate it. if (instance_) { gtk_window_present(GTK_WINDOW(instance_->dialog_)); } else { - instance_ = new CookiesView(profile, browsing_data_local_storage_helper); + instance_ = new CookiesView(profile, + browsing_data_database_helper, + browsing_data_local_storage_helper); instance_->InitStylesAndShow(); } } CookiesView::CookiesView( Profile* profile, + BrowsingDataDatabaseHelper* browsing_data_database_helper, BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper) : profile_(profile), + browsing_data_database_helper_(browsing_data_database_helper), browsing_data_local_storage_helper_(browsing_data_local_storage_helper), filter_update_factory_(this) { Init(); @@ -166,8 +172,9 @@ void CookiesView::Init() { GTK_SHADOW_ETCHED_IN); gtk_box_pack_start(GTK_BOX(cookie_list_vbox), scroll_window, TRUE, TRUE, 0); - cookies_tree_model_.reset(new CookiesTreeModel( - profile_, browsing_data_local_storage_helper_)); + cookies_tree_model_.reset(new CookiesTreeModel(profile_, + browsing_data_database_helper_, + browsing_data_local_storage_helper_)); cookies_tree_adapter_.reset( new gtk_tree::TreeAdapter(this, cookies_tree_model_.get())); tree_ = gtk_tree_view_new_with_model( @@ -226,6 +233,27 @@ void CookiesView::Init() { InitDetailRow(row++, IDS_COOKIES_COOKIE_EXPIRES_LABEL, cookie_details_table_, &cookie_expires_entry_); + // Database details. + GtkWidget* database_details_frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(database_details_frame), + GTK_SHADOW_ETCHED_IN); + gtk_box_pack_start(GTK_BOX(cookie_list_vbox), database_details_frame, + FALSE, FALSE, 0); + database_details_table_ = gtk_table_new(3, 2, FALSE); + gtk_container_add(GTK_CONTAINER(database_details_frame), + database_details_table_); + gtk_table_set_col_spacing(GTK_TABLE(database_details_table_), 0, + gtk_util::kLabelSpacing); + + row = 0; + InitDetailRow(row++, IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL, + database_details_table_, &database_description_entry_); + InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL, + database_details_table_, &database_size_entry_); + InitDetailRow(row++, IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL, + database_details_table_, + &database_last_modified_entry_); + // Local storage details. GtkWidget* local_storage_details_frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(local_storage_details_frame), @@ -270,6 +298,13 @@ void CookiesView::InitStylesAndShow() { InitBrowserDetailStyle(cookie_created_entry_, label_style, dialog_style); InitBrowserDetailStyle(cookie_expires_entry_, label_style, dialog_style); + // Database details. + InitBrowserDetailStyle(database_description_entry_, label_style, + dialog_style); + InitBrowserDetailStyle(database_size_entry_, label_style, dialog_style); + InitBrowserDetailStyle(database_last_modified_entry_, label_style, + dialog_style); + // Local storage details. InitBrowserDetailStyle(local_storage_origin_entry_, label_style, dialog_style); @@ -321,6 +356,10 @@ void CookiesView::EnableControls() { PopulateCookieDetails(detailed_info.cookie->first, detailed_info.cookie->second); } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_DATABASE) { + UpdateVisibleDetailedInfo(database_details_table_); + PopulateDatabaseDetails(*detailed_info.database_info); + } else if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { UpdateVisibleDetailedInfo(local_storage_details_table_); PopulateLocalStorageDetails(*detailed_info.local_storage_info); @@ -343,6 +382,12 @@ void CookiesView::SetCookieDetailsSensitivity(gboolean enabled) { gtk_widget_set_sensitive(cookie_expires_entry_, enabled); } +void CookiesView::SetDatabaseDetailsSensitivity(gboolean enabled) { + gtk_widget_set_sensitive(database_description_entry_, enabled); + gtk_widget_set_sensitive(database_size_entry_, enabled); + gtk_widget_set_sensitive(database_last_modified_entry_, enabled); +} + void CookiesView::SetLocalStorageDetailsSensitivity(gboolean enabled) { gtk_widget_set_sensitive(local_storage_origin_entry_, enabled); gtk_widget_set_sensitive(local_storage_size_entry_, enabled); @@ -376,6 +421,21 @@ void CookiesView::PopulateCookieDetails( SetCookieDetailsSensitivity(TRUE); } +void CookiesView::PopulateDatabaseDetails( + const BrowsingDataDatabaseHelper::DatabaseInfo& database_info) { + gtk_entry_set_text(GTK_ENTRY(database_description_entry_), + database_info.description.c_str()); + gtk_entry_set_text(GTK_ENTRY(database_size_entry_), + WideToUTF8(FormatBytes( + database_info.size, + GetByteDisplayUnits(database_info.size), + true)).c_str()); + gtk_entry_set_text(GTK_ENTRY(database_last_modified_entry_), + WideToUTF8(base::TimeFormatFriendlyDateAndTime( + database_info.last_modified)).c_str()); + SetDatabaseDetailsSensitivity(TRUE); +} + void CookiesView::PopulateLocalStorageDetails( const BrowsingDataLocalStorageHelper::LocalStorageInfo& local_storage_info) { @@ -452,8 +512,7 @@ void CookiesView::OnResponse(GtkDialog* dialog, int response_id, if (response_id == RESPONSE_REMOVE) { window->RemoveSelectedItems(); } else if (response_id == RESPONSE_REMOVE_ALL) { - window->cookies_tree_model_->DeleteAllCookies(); - window->browsing_data_local_storage_helper_->DeleteAllLocalStorageFiles(); + window->cookies_tree_model_->DeleteAllStoredObjects(); } else { gtk_widget_destroy(window->dialog_); } @@ -505,18 +564,18 @@ void CookiesView::UpdateFilterResults() { } void CookiesView::UpdateVisibleDetailedInfo(GtkWidget* table) { + SetCookieDetailsSensitivity(table == cookie_details_table_); + SetDatabaseDetailsSensitivity(table == database_details_table_); + SetLocalStorageDetailsSensitivity(table == local_storage_details_table_); // Toggle the parent (the table frame) visibility and sensitivity. gtk_widget_show(gtk_widget_get_parent(table)); // Toggle the other tables. - if (table == cookie_details_table_) { - SetCookieDetailsSensitivity(true); - SetLocalStorageDetailsSensitivity(false); - gtk_widget_hide(gtk_widget_get_parent(local_storage_details_table_)); - } else if (table == local_storage_details_table_) { - SetCookieDetailsSensitivity(false); - SetLocalStorageDetailsSensitivity(true); + if (table != cookie_details_table_) gtk_widget_hide(gtk_widget_get_parent(cookie_details_table_)); - } + if (table != database_details_table_) + gtk_widget_hide(gtk_widget_get_parent(database_details_table_)); + if (table != local_storage_details_table_) + gtk_widget_hide(gtk_widget_get_parent(local_storage_details_table_)); } // static diff --git a/chrome/browser/gtk/options/cookies_view.h b/chrome/browser/gtk/options/cookies_view.h index 7720e13..80cad06 100644 --- a/chrome/browser/gtk/options/cookies_view.h +++ b/chrome/browser/gtk/options/cookies_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/task.h" +#include "chrome/browser/browsing_data_database_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "chrome/common/gtk_tree.h" #include "net/base/cookie_monster.h" @@ -34,6 +35,7 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { // Create (if necessary) and show the cookie manager window. static void Show( Profile* profile, + BrowsingDataDatabaseHelper* browsing_data_database_helper, BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); // gtk_tree::TreeAdapter::Delegate implementation. @@ -43,6 +45,7 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { private: CookiesView( Profile* profile, + BrowsingDataDatabaseHelper* browsing_data_database_helper, BrowsingDataLocalStorageHelper* browsing_data_local_storage_helper); // Initialize the dialog contents and layout. @@ -64,6 +67,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { // Set sensitivity of cookie details. void SetCookieDetailsSensitivity(gboolean enabled); + // Set sensitivity of database details. + void SetDatabaseDetailsSensitivity(gboolean enabled); + // Set sensitivity of local storage details. void SetLocalStorageDetailsSensitivity(gboolean enabled); @@ -71,6 +77,10 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { void PopulateCookieDetails(const std::string& domain, const net::CookieMonster::CanonicalCookie& cookie); + // Show the details of the currently selected database. + void PopulateDatabaseDetails( + const BrowsingDataDatabaseHelper::DatabaseInfo& database_info); + // Show the details of the currently selected local storage. void PopulateLocalStorageDetails( const BrowsingDataLocalStorageHelper::LocalStorageInfo& @@ -137,6 +147,12 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { GtkWidget* cookie_created_entry_; GtkWidget* cookie_expires_entry_; + // The database details widgets. + GtkWidget* database_details_table_; + GtkWidget* database_description_entry_; + GtkWidget* database_size_entry_; + GtkWidget* database_last_modified_entry_; + // The local storage details widgets. GtkWidget* local_storage_details_table_; GtkWidget* local_storage_origin_entry_; @@ -146,6 +162,9 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { // The profile. Profile* profile_; + // Database Helper. + scoped_refptr<BrowsingDataDatabaseHelper> browsing_data_database_helper_; + // Local Storage Helper. scoped_refptr<BrowsingDataLocalStorageHelper> browsing_data_local_storage_helper_; @@ -164,7 +183,7 @@ class CookiesView : public gtk_tree::TreeAdapter::Delegate { FRIEND_TEST(CookiesViewTest, RemoveAll); FRIEND_TEST(CookiesViewTest, RemoveAllWithDefaultSelected); FRIEND_TEST(CookiesViewTest, Remove); - FRIEND_TEST(CookiesViewTest, RemoveCookiesByDomain); + FRIEND_TEST(CookiesViewTest, RemoveCookiesByType); FRIEND_TEST(CookiesViewTest, RemoveByDomain); FRIEND_TEST(CookiesViewTest, RemoveDefaultSelection); FRIEND_TEST(CookiesViewTest, Filter); diff --git a/chrome/browser/gtk/options/cookies_view_unittest.cc b/chrome/browser/gtk/options/cookies_view_unittest.cc index 4092dbf..501bb0a 100644 --- a/chrome/browser/gtk/options/cookies_view_unittest.cc +++ b/chrome/browser/gtk/options/cookies_view_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,7 @@ #include <gtk/gtk.h> #include "base/string_util.h" +#include "chrome/browser/mock_browsing_data_database_helper.h" #include "chrome/browser/mock_browsing_data_local_storage_helper.h" #include "chrome/browser/net/url_request_context_getter.h" #include "chrome/test/testing_profile.h" @@ -27,11 +28,14 @@ class CookiesViewTest : public testing::Test { virtual void SetUp() { profile_.reset(new TestingProfile()); profile_->CreateRequestContext(); - mock_browsing_data_helper_ = new MockBrowsingDataLocalStorageHelper( - profile_.get()); + mock_browsing_data_database_helper_ = + new MockBrowsingDataDatabaseHelper(profile_.get()); + mock_browsing_data_local_storage_helper_ = + new MockBrowsingDataLocalStorageHelper(profile_.get()); } void CheckDetailsSensitivity(gboolean expected_cookies, + gboolean expected_database, gboolean expected_local_storage, const CookiesView& cookies_view) { // Cookies @@ -49,6 +53,14 @@ class CookiesViewTest : public testing::Test { GTK_WIDGET_SENSITIVE(cookies_view.cookie_created_entry_)); EXPECT_EQ(expected_cookies, GTK_WIDGET_SENSITIVE(cookies_view.cookie_expires_entry_)); + // Database + EXPECT_EQ(expected_database, + GTK_WIDGET_SENSITIVE(cookies_view.database_description_entry_)); + EXPECT_EQ(expected_database, + GTK_WIDGET_SENSITIVE(cookies_view.database_size_entry_)); + EXPECT_EQ(expected_database, + GTK_WIDGET_SENSITIVE( + cookies_view.database_last_modified_entry_)); // Local Storage EXPECT_EQ(expected_local_storage, GTK_WIDGET_SENSITIVE(cookies_view.local_storage_origin_entry_)); @@ -162,14 +174,19 @@ class CookiesViewTest : public testing::Test { ChromeThread io_thread_; scoped_ptr<TestingProfile> profile_; - scoped_refptr<MockBrowsingDataLocalStorageHelper> mock_browsing_data_helper_; + scoped_refptr<MockBrowsingDataDatabaseHelper> + mock_browsing_data_database_helper_; + scoped_refptr<MockBrowsingDataLocalStorageHelper> + mock_browsing_data_local_storage_helper_; }; TEST_F(CookiesViewTest, Empty) { - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); } @@ -182,27 +199,37 @@ TEST_F(CookiesViewTest, Noop) { monster->SetCookie(GURL("http://foo1"), "E=1"); monster->SetCookie(GURL("http://foo2"), "G=1"); monster->SetCookie(GURL("http://foo2"), "X=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1,_Cookies,__A,__B,__E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); } TEST_F(CookiesViewTest, RemoveAll) { net::CookieMonster* monster = profile_->GetCookieMonster(); monster->SetCookie(GURL("http://foo"), "A=1"); monster->SetCookie(GURL("http://foo2"), "B=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); // Reset the selection of the first row. gtk_tree_selection_unselect_all(cookies_view.selection_); @@ -211,22 +238,28 @@ TEST_F(CookiesViewTest, RemoveAll) { SCOPED_TRACE("Before removing"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo,_Cookies,__A,foo2,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); } + mock_browsing_data_database_helper_->Reset(); + mock_browsing_data_local_storage_helper_->Reset(); + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_all_button_)); { SCOPED_TRACE("After removing"); EXPECT_EQ(0u, monster->GetAllCookies().size()); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); - EXPECT_TRUE(mock_browsing_data_helper_->delete_all_files_called_); + EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted()); } } @@ -234,9 +267,13 @@ TEST_F(CookiesViewTest, RemoveAllWithDefaultSelected) { net::CookieMonster* monster = profile_->GetCookieMonster(); monster->SetCookie(GURL("http://foo"), "A=1"); monster->SetCookie(GURL("http://foo2"), "B=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); EXPECT_EQ(1, gtk_tree_selection_count_selected_rows(cookies_view.selection_)); @@ -244,24 +281,30 @@ TEST_F(CookiesViewTest, RemoveAllWithDefaultSelected) { SCOPED_TRACE("Before removing"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo,_Cookies,__A,foo2,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); } + mock_browsing_data_database_helper_->Reset(); + mock_browsing_data_local_storage_helper_->Reset(); + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_all_button_)); { SCOPED_TRACE("After removing"); EXPECT_EQ(0u, monster->GetAllCookies().size()); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(0, gtk_tree_selection_count_selected_rows(cookies_view.selection_)); - EXPECT_TRUE(mock_browsing_data_helper_->delete_all_files_called_); + EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted()); + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted()); } } @@ -270,9 +313,13 @@ TEST_F(CookiesViewTest, Remove) { monster->SetCookie(GURL("http://foo1"), "A=1"); monster->SetCookie(GURL("http://foo2"), "B=1"); monster->SetCookie(GURL("http://foo2"), "C=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); ASSERT_TRUE(ExpandByPath(cookies_view, "1")); ASSERT_TRUE(SelectByPath(cookies_view, "1:0:0")); @@ -281,8 +328,10 @@ TEST_F(CookiesViewTest, Remove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(TRUE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,_Cookies,__A,foo2,+Cookies,++B,++C," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -294,13 +343,15 @@ TEST_F(CookiesViewTest, Remove) { SCOPED_TRACE("First selection removed"); EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo1,_Cookies,__A,foo2,+Cookies,++C," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(TRUE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); } EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); @@ -310,17 +361,21 @@ TEST_F(CookiesViewTest, Remove) { SCOPED_TRACE("Second selection"); EXPECT_STREQ("A", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo1,_Cookies,__A,foo2,+Cookies," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); } ASSERT_TRUE(ExpandByPath(cookies_view, "0")); EXPECT_STREQ("foo1,+Cookies,++A,foo2,+Cookies," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -334,8 +389,10 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -343,7 +400,9 @@ TEST_F(CookiesViewTest, Remove) { ASSERT_TRUE(ExpandByPath(cookies_view, "2")); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," - "host1,+Local Storage,++origin1," + "gdbhost1,+Web Databases,++db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); ASSERT_TRUE(SelectByPath(cookies_view, "2:0:0")); @@ -356,17 +415,49 @@ TEST_F(CookiesViewTest, Remove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("2:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," + "gdbhost1,+Web Databases," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_origin_ == + "http_gdbhost1_1"); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_db_ == + "db1"); + } + + ASSERT_TRUE(ExpandByPath(cookies_view, "4")); + EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," + "gdbhost1,+Web Databases," + "gdbhost2,_Web Databases,__db2," + "host1,+Local Storage,++origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + ASSERT_TRUE(SelectByPath(cookies_view, "4:0:0")); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + { + SCOPED_TRACE("Fourth selection removed"); + EXPECT_EQ(0u, monster->GetAllCookies().size()); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_STREQ("4:0", GetSelectedPath(cookies_view).c_str()); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + EXPECT_STREQ("foo1,+Cookies,foo2,+Cookies," + "gdbhost1,+Web Databases," + "gdbhost2,_Web Databases,__db2," "host1,+Local Storage," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); - EXPECT_TRUE(mock_browsing_data_helper_->last_deleted_file_ == + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->last_deleted_file_ == FilePath(FILE_PATH_LITERAL("file1"))); } } -TEST_F(CookiesViewTest, RemoveCookiesByDomain) { +TEST_F(CookiesViewTest, RemoveCookiesByType) { net::CookieMonster* monster = profile_->GetCookieMonster(); monster->SetCookie(GURL("http://foo0"), "C=1"); monster->SetCookie(GURL("http://foo0"), "D=1"); @@ -375,13 +466,19 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { monster->SetCookie(GURL("http://foo1"), "E=1"); monster->SetCookie(GURL("http://foo2"), "G=1"); monster->SetCookie(GURL("http://foo2"), "X=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1,_Cookies,__A,__B,__E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -390,6 +487,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1,+Cookies,++A,++B,++E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -404,6 +503,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -415,6 +516,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0,+Cookies,++C,++D," "foo1," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -425,6 +528,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0," "foo1," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -436,6 +541,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0," "foo1," "foo2,+Cookies,++G,++X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -446,6 +553,8 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0," "foo1," "foo2," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -457,7 +566,9 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0," "foo1," "foo2," - "host1,+Local Storage,++origin1," + "gdbhost1,+Web Databases,++db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); ASSERT_TRUE(SelectByPath(cookies_view, "3:0")); @@ -467,13 +578,44 @@ TEST_F(CookiesViewTest, RemoveCookiesByDomain) { EXPECT_STREQ("foo0," "foo1," "foo2," - "host1," + "gdbhost1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("3", GetSelectedPath(cookies_view).c_str()); - EXPECT_TRUE(mock_browsing_data_helper_->last_deleted_file_ == + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_origin_ == + "http_gdbhost1_1"); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_db_ == + "db1"); + + ASSERT_TRUE(ExpandByPath(cookies_view, "5")); + EXPECT_STREQ("foo0," + "foo1," + "foo2," + "gdbhost1," + "gdbhost2,_Web Databases,__db2," + "host1,+Local Storage,++origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + ASSERT_TRUE(SelectByPath(cookies_view, "5:0")); + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + EXPECT_STREQ("", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("foo0," + "foo1," + "foo2," + "gdbhost1," + "gdbhost2,_Web Databases,__db2," + "host1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_STREQ("5", GetSelectedPath(cookies_view).c_str()); + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->last_deleted_file_ == FilePath(FILE_PATH_LITERAL("file1"))); } @@ -486,13 +628,19 @@ TEST_F(CookiesViewTest, RemoveByDomain) { monster->SetCookie(GURL("http://foo1"), "E=1"); monster->SetCookie(GURL("http://foo2"), "G=1"); monster->SetCookie(GURL("http://foo2"), "X=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1,_Cookies,__A,__B,__E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -507,6 +655,8 @@ TEST_F(CookiesViewTest, RemoveByDomain) { EXPECT_STREQ("C,D,G,X", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -519,11 +669,40 @@ TEST_F(CookiesViewTest, RemoveByDomain) { EXPECT_STREQ("G,X", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + EXPECT_STREQ("", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + EXPECT_STREQ("", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_origin_ == + "http_gdbhost1_1"); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_db_ == + "db1"); EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -534,6 +713,10 @@ TEST_F(CookiesViewTest, RemoveByDomain) { GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_origin_ == + "http_gdbhost2_2"); + EXPECT_TRUE(mock_browsing_data_database_helper_->last_deleted_db_ == + "db2"); EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -543,7 +726,7 @@ TEST_F(CookiesViewTest, RemoveByDomain) { GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - EXPECT_TRUE(mock_browsing_data_helper_->last_deleted_file_ == + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->last_deleted_file_ == FilePath(FILE_PATH_LITERAL("file1"))); EXPECT_STREQ("0", GetSelectedPath(cookies_view).c_str()); @@ -553,7 +736,7 @@ TEST_F(CookiesViewTest, RemoveByDomain) { GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(FALSE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - EXPECT_TRUE(mock_browsing_data_helper_->last_deleted_file_ == + EXPECT_TRUE(mock_browsing_data_local_storage_helper_->last_deleted_file_ == FilePath(FILE_PATH_LITERAL("file2"))); EXPECT_EQ(0, gtk_tree_selection_count_selected_rows(cookies_view.selection_)); @@ -568,13 +751,19 @@ TEST_F(CookiesViewTest, RemoveDefaultSelection) { monster->SetCookie(GURL("http://foo1"), "E=1"); monster->SetCookie(GURL("http://foo2"), "G=1"); monster->SetCookie(GURL("http://foo2"), "X=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("foo0,_Cookies,__C,__D," "foo1,_Cookies,__A,__B,__E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -588,6 +777,8 @@ TEST_F(CookiesViewTest, RemoveDefaultSelection) { EXPECT_STREQ("B,A,E,G,X", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo1,_Cookies,__A,__B,__E," "foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -599,6 +790,31 @@ TEST_F(CookiesViewTest, RemoveDefaultSelection) { EXPECT_STREQ("G,X", GetMonsterCookies(monster).c_str()); EXPECT_STREQ("foo2,_Cookies,__G,__X," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + EXPECT_STREQ("", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", + GetDisplayedCookies(cookies_view).c_str()); + + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + EXPECT_STREQ("", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -640,14 +856,20 @@ TEST_F(CookiesViewTest, Filter) { monster->SetCookie(GURL("http://bar0"), "D=1"); monster->SetCookie(GURL("http://foo1"), "B=1"); monster->SetCookie(GURL("http://bar1"), "A=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("bar0,_Cookies,__D," "bar1,_Cookies,__A," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -661,6 +883,8 @@ TEST_F(CookiesViewTest, Filter) { "bar1,_Cookies,__A," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -678,13 +902,17 @@ TEST_F(CookiesViewTest, Filter) { "bar1,_Cookies,__A," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); gtk_entry_set_text(GTK_ENTRY(cookies_view.filter_entry_), "hos"); gtk_widget_activate(cookies_view.filter_entry_); - EXPECT_STREQ("host1,_Local Storage,__origin1," + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); } @@ -695,14 +923,20 @@ TEST_F(CookiesViewTest, FilterRemoveAll) { monster->SetCookie(GURL("http://bar0"), "D=1"); monster->SetCookie(GURL("http://foo1"), "B=1"); monster->SetCookie(GURL("http://bar1"), "A=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("bar0,_Cookies,__D," "bar1,_Cookies,__A," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -716,6 +950,8 @@ TEST_F(CookiesViewTest, FilterRemoveAll) { "bar1,_Cookies,__A," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -739,6 +975,8 @@ TEST_F(CookiesViewTest, FilterRemoveAll) { EXPECT_STREQ("", gtk_entry_get_text(GTK_ENTRY(cookies_view.filter_entry_))); EXPECT_STREQ("foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -751,14 +989,20 @@ TEST_F(CookiesViewTest, FilterRemove) { monster->SetCookie(GURL("http://foo1"), "B=1"); monster->SetCookie(GURL("http://bar1"), "A=1"); monster->SetCookie(GURL("http://bar1"), "E=1"); - CookiesView cookies_view(profile_.get(), mock_browsing_data_helper_); - mock_browsing_data_helper_->AddLocalStorageSamples(); - mock_browsing_data_helper_->Notify(); + CookiesView cookies_view(profile_.get(), + mock_browsing_data_database_helper_, + mock_browsing_data_local_storage_helper_); + mock_browsing_data_database_helper_->AddDatabaseSamples(); + mock_browsing_data_database_helper_->Notify(); + mock_browsing_data_local_storage_helper_->AddLocalStorageSamples(); + mock_browsing_data_local_storage_helper_->Notify(); EXPECT_STREQ("bar0,_Cookies,__D," "bar1,_Cookies,__A,__E," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -773,6 +1017,8 @@ TEST_F(CookiesViewTest, FilterRemove) { "bar1,_Cookies,__A,__E," "foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -793,7 +1039,7 @@ TEST_F(CookiesViewTest, FilterRemove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(TRUE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -807,7 +1053,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(TRUE, FALSE, cookies_view); + CheckDetailsSensitivity(TRUE, FALSE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -821,7 +1067,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); } ASSERT_TRUE(ExpandByPath(cookies_view, "0")); @@ -835,7 +1081,7 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("0:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); EXPECT_STREQ("bar0,+Cookies," "bar1,+Cookies", GetDisplayedCookies(cookies_view).c_str()); @@ -846,6 +1092,8 @@ TEST_F(CookiesViewTest, FilterRemove) { EXPECT_STREQ("", gtk_entry_get_text(GTK_ENTRY(cookies_view.filter_entry_))); EXPECT_STREQ("foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); @@ -855,19 +1103,25 @@ TEST_F(CookiesViewTest, FilterRemove) { // Entering text doesn't immediately filter the results. EXPECT_STREQ("foo0,_Cookies,__C," "foo1,_Cookies,__B," + "gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); // Results are filtered immediately if you activate (hit enter in the entry). gtk_widget_activate(cookies_view.filter_entry_); - EXPECT_STREQ("host1,_Local Storage,__origin1," + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,_Web Databases,__db2," + "host1,_Local Storage,__origin1," "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); ASSERT_TRUE(ExpandByPath(cookies_view, "1")); - EXPECT_STREQ("host1,_Local Storage,__origin1," - "host2,+Local Storage,++origin2", + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,+Web Databases,++db2," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); ASSERT_TRUE(SelectByPath(cookies_view, "1:0:0")); @@ -875,7 +1129,7 @@ TEST_F(CookiesViewTest, FilterRemove) { SCOPED_TRACE("First selection"); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); - CheckDetailsSensitivity(FALSE, TRUE, cookies_view); + CheckDetailsSensitivity(FALSE, TRUE, FALSE, cookies_view); } gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); @@ -883,12 +1137,45 @@ TEST_F(CookiesViewTest, FilterRemove) { { SCOPED_TRACE("First selection removed"); EXPECT_STREQ("C,B", GetMonsterCookies(monster).c_str()); - EXPECT_STREQ("host1,_Local Storage,__origin1," - "host2,+Local Storage", + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,+Web Databases," + "host1,_Local Storage,__origin1," + "host2,_Local Storage,__origin2", GetDisplayedCookies(cookies_view).c_str()); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); EXPECT_STREQ("1:0", GetSelectedPath(cookies_view).c_str()); - CheckDetailsSensitivity(FALSE, FALSE, cookies_view); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); + } + + ASSERT_TRUE(ExpandByPath(cookies_view, "3")); + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,+Web Databases," + "host1,_Local Storage,__origin1," + "host2,+Local Storage,++origin2", + GetDisplayedCookies(cookies_view).c_str()); + ASSERT_TRUE(SelectByPath(cookies_view, "3:0:0")); + + { + SCOPED_TRACE("First selection"); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + CheckDetailsSensitivity(FALSE, FALSE, TRUE, cookies_view); + } + + gtk_button_clicked(GTK_BUTTON(cookies_view.remove_button_)); + + { + SCOPED_TRACE("First selection removed"); + EXPECT_STREQ("C,B", GetMonsterCookies(monster).c_str()); + EXPECT_STREQ("gdbhost1,_Web Databases,__db1," + "gdbhost2,+Web Databases," + "host1,_Local Storage,__origin1," + "host2,+Local Storage", + GetDisplayedCookies(cookies_view).c_str()); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_all_button_)); + EXPECT_EQ(TRUE, GTK_WIDGET_SENSITIVE(cookies_view.remove_button_)); + EXPECT_STREQ("3:0", GetSelectedPath(cookies_view).c_str()); + CheckDetailsSensitivity(FALSE, FALSE, FALSE, cookies_view); } } diff --git a/chrome/browser/mock_browsing_data_database_helper.cc b/chrome/browser/mock_browsing_data_database_helper.cc new file mode 100644 index 0000000..4e708a8 --- /dev/null +++ b/chrome/browser/mock_browsing_data_database_helper.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/mock_browsing_data_database_helper.h" + +MockBrowsingDataDatabaseHelper::MockBrowsingDataDatabaseHelper( + Profile* profile) + : BrowsingDataDatabaseHelper(profile), + profile_(profile) { +} + +MockBrowsingDataDatabaseHelper::~MockBrowsingDataDatabaseHelper() { +} + +void MockBrowsingDataDatabaseHelper::StartFetching( + Callback1<const std::vector<DatabaseInfo>& >::Type* callback) { + callback_.reset(callback); +} + +void MockBrowsingDataDatabaseHelper::CancelNotification() { + callback_.reset(NULL); +} + +void MockBrowsingDataDatabaseHelper::DeleteDatabase( + const std::string& origin, + const std::string& name) { + std::string key = origin + ":" + name; + CHECK(databases_.find(key) != databases_.end()); + last_deleted_origin_ = origin; + last_deleted_db_ = name; + databases_[key] = false; +} + +void MockBrowsingDataDatabaseHelper::AddDatabaseSamples() { + response_.push_back(BrowsingDataDatabaseHelper::DatabaseInfo( + "gdbhost1", "db1", "http_gdbhost1_1", "description 1", 1, base::Time())); + databases_["http_gdbhost1_1:db1"] = true; + response_.push_back(BrowsingDataDatabaseHelper::DatabaseInfo( + "gdbhost2", "db2", "http_gdbhost2_2", "description 2", 2, base::Time())); + databases_["http_gdbhost2_2:db2"] = true; +} + +void MockBrowsingDataDatabaseHelper::Notify() { + CHECK(callback_.get()); + callback_->Run(response_); +} + +void MockBrowsingDataDatabaseHelper::Reset() { + for (std::map<const std::string, bool>::iterator i = databases_.begin(); + i != databases_.end(); ++i) + i->second = true; +} + +bool MockBrowsingDataDatabaseHelper::AllDeleted() { + for (std::map<const std::string, bool>::const_iterator i = databases_.begin(); + i != databases_.end(); ++i) + if (i->second) + return false; + return true; +} diff --git a/chrome/browser/mock_browsing_data_database_helper.h b/chrome/browser/mock_browsing_data_database_helper.h new file mode 100644 index 0000000..ea84d51 --- /dev/null +++ b/chrome/browser/mock_browsing_data_database_helper.h @@ -0,0 +1,58 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MOCK_BROWSING_DATA_DATABASE_HELPER_H_ +#define CHROME_BROWSER_MOCK_BROWSING_DATA_DATABASE_HELPER_H_ + +#include <map> + +#include "chrome/browser/browsing_data_database_helper.h" + +// Mock for BrowsingDataDatabaseHelper. +// Use AddDatabaseSamples() or add directly to response_ vector, then call +// Notify(). +class MockBrowsingDataDatabaseHelper : public BrowsingDataDatabaseHelper { + public: + explicit MockBrowsingDataDatabaseHelper(Profile* profile); + + virtual void StartFetching( + Callback1<const std::vector<DatabaseInfo>& >::Type* callback); + + virtual void CancelNotification(); + + virtual void DeleteDatabase(const std::string& origin, + const std::string& name); + + // Adds some DatabaseInfo samples. + void AddDatabaseSamples(); + + // Notifies the callback. + void Notify(); + + // Marks all databases as existing. + void Reset(); + + // Returns true if all databases since the last Reset() invokation were + // deleted. + bool AllDeleted(); + + std::string last_deleted_origin_; + + std::string last_deleted_db_; + + private: + virtual ~MockBrowsingDataDatabaseHelper(); + + Profile* profile_; + + scoped_ptr<Callback1<const std::vector<DatabaseInfo>& >::Type > + callback_; + + // Stores which databases exist. + std::map<const std::string, bool> databases_; + + std::vector<DatabaseInfo> response_; +}; + +#endif // CHROME_BROWSER_MOCK_BROWSING_DATA_DATABASE_HELPER_H_ diff --git a/chrome/browser/mock_browsing_data_local_storage_helper.cc b/chrome/browser/mock_browsing_data_local_storage_helper.cc index 26c8968..f034203 100644 --- a/chrome/browser/mock_browsing_data_local_storage_helper.cc +++ b/chrome/browser/mock_browsing_data_local_storage_helper.cc @@ -7,8 +7,7 @@ MockBrowsingDataLocalStorageHelper::MockBrowsingDataLocalStorageHelper( Profile* profile) : BrowsingDataLocalStorageHelper(profile), - profile_(profile), - delete_all_files_called_(false) { + profile_(profile) { } MockBrowsingDataLocalStorageHelper::~MockBrowsingDataLocalStorageHelper() { @@ -25,11 +24,9 @@ void MockBrowsingDataLocalStorageHelper::CancelNotification() { void MockBrowsingDataLocalStorageHelper::DeleteLocalStorageFile( const FilePath& file_path) { + CHECK(files_.find(file_path.value()) != files_.end()); last_deleted_file_ = file_path; -} - -void MockBrowsingDataLocalStorageHelper::DeleteAllLocalStorageFiles() { - delete_all_files_called_ = true; + files_[file_path.value()] = false; } void MockBrowsingDataLocalStorageHelper::AddLocalStorageSamples() { @@ -37,13 +34,29 @@ void MockBrowsingDataLocalStorageHelper::AddLocalStorageSamples() { BrowsingDataLocalStorageHelper::LocalStorageInfo( "http", "host1", 1, "db1", "origin1", FilePath(FILE_PATH_LITERAL("file1")), 1, base::Time())); + files_[FILE_PATH_LITERAL("file1")] = true; response_.push_back( BrowsingDataLocalStorageHelper::LocalStorageInfo( "http", "host2", 2, "db2", "origin2", FilePath(FILE_PATH_LITERAL("file2")), 2, base::Time())); + files_[FILE_PATH_LITERAL("file2")] = true; } void MockBrowsingDataLocalStorageHelper::Notify() { CHECK(callback_.get()); callback_->Run(response_); } + +void MockBrowsingDataLocalStorageHelper::Reset() { + for (std::map<const FilePath::StringType, bool>::iterator i = files_.begin(); + i != files_.end(); ++i) + i->second = true; +} + +bool MockBrowsingDataLocalStorageHelper::AllDeleted() { + for (std::map<const FilePath::StringType, bool>::const_iterator i = + files_.begin(); i != files_.end(); ++i) + if (i->second) + return false; + return true; +} diff --git a/chrome/browser/mock_browsing_data_local_storage_helper.h b/chrome/browser/mock_browsing_data_local_storage_helper.h index 2b36b49..89df123 100644 --- a/chrome/browser/mock_browsing_data_local_storage_helper.h +++ b/chrome/browser/mock_browsing_data_local_storage_helper.h @@ -1,10 +1,12 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_MOCK_BROWSING_DATA_LOCAL_STORAGE_HELPER_H_ #define CHROME_BROWSER_MOCK_BROWSING_DATA_LOCAL_STORAGE_HELPER_H_ +#include <map> + #include "chrome/browser/browsing_data_local_storage_helper.h" // Mock for BrowsingDataLocalStorageHelper. @@ -14,13 +16,13 @@ class MockBrowsingDataLocalStorageHelper : public BrowsingDataLocalStorageHelper { public: explicit MockBrowsingDataLocalStorageHelper(Profile* profile); - virtual ~MockBrowsingDataLocalStorageHelper(); virtual void StartFetching( Callback1<const std::vector<LocalStorageInfo>& >::Type* callback); + virtual void CancelNotification(); + virtual void DeleteLocalStorageFile(const FilePath& file_path); - virtual void DeleteAllLocalStorageFiles(); // Adds some LocalStorageInfo samples. void AddLocalStorageSamples(); @@ -28,11 +30,25 @@ class MockBrowsingDataLocalStorageHelper // Notifies the callback. void Notify(); + // Marks all local storage files as existing. + void Reset(); + + // Returns true if all local storage files were deleted since the last + // Reset() invokation. + bool AllDeleted(); + + FilePath last_deleted_file_; + + private: + virtual ~MockBrowsingDataLocalStorageHelper(); + Profile* profile_; + scoped_ptr<Callback1<const std::vector<LocalStorageInfo>& >::Type > callback_; - FilePath last_deleted_file_; - bool delete_all_files_called_; + + std::map<const FilePath::StringType, bool> files_; + std::vector<LocalStorageInfo> response_; }; diff --git a/chrome/browser/views/database_info_view.cc b/chrome/browser/views/database_info_view.cc new file mode 100755 index 0000000..aff6df5 --- /dev/null +++ b/chrome/browser/views/database_info_view.cc @@ -0,0 +1,131 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/database_info_view.h" + +#include <algorithm> + +#include "app/gfx/color_utils.h" +#include "app/l10n_util.h" +#include "base/i18n/time_formatting.h" +#include "base/string_util.h" +#include "grit/generated_resources.h" +#include "views/grid_layout.h" +#include "views/controls/label.h" +#include "views/controls/textfield/textfield.h" +#include "views/standard_layout.h" + +static const int kDatabaseInfoViewBorderSize = 1; +static const int kDatabaseInfoViewInsetSize = 3; + +/////////////////////////////////////////////////////////////////////////////// +// DatabaseInfoView, public: + +DatabaseInfoView::DatabaseInfoView() + : description_value_field_(NULL), + size_value_field_(NULL), + last_modified_value_field_(NULL) { +} + +DatabaseInfoView::~DatabaseInfoView() { +} + +void DatabaseInfoView::SetDatabaseInfo( + const BrowsingDataDatabaseHelper::DatabaseInfo& database_info) { + description_value_field_->SetText(UTF8ToWide(database_info.description)); + size_value_field_->SetText( + FormatBytes(database_info.size, + GetByteDisplayUnits(database_info.size), + true)); + last_modified_value_field_->SetText( + base::TimeFormatFriendlyDateAndTime(database_info.last_modified)); + EnableDatabaseDisplay(true); +} + +void DatabaseInfoView::EnableDatabaseDisplay(bool enabled) { + description_value_field_->SetEnabled(enabled); + size_value_field_->SetEnabled(enabled); + last_modified_value_field_->SetEnabled(enabled); +} + +void DatabaseInfoView::ClearDatabaseDisplay() { + std::wstring no_cookie_string = + l10n_util::GetString(IDS_COOKIES_COOKIE_NONESELECTED); + description_value_field_->SetText(no_cookie_string); + size_value_field_->SetText(no_cookie_string); + last_modified_value_field_->SetText(no_cookie_string); + EnableDatabaseDisplay(false); +} + +/////////////////////////////////////////////////////////////////////////////// +// DatabaseInfoView, views::View overrides: + +void DatabaseInfoView::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) + Init(); +} + +/////////////////////////////////////////////////////////////////////////////// +// DatabaseInfoView, private: + +void DatabaseInfoView::Init() { + SkColor border_color = color_utils::GetSysSkColor(COLOR_3DSHADOW); + views::Border* border = views::Border::CreateSolidBorder( + kDatabaseInfoViewBorderSize, border_color); + set_border(border); + + views::Label* description_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_WEB_DATABASE_DESCRIPTION_LABEL)); + description_value_field_ = new views::Textfield; + views::Label* size_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL)); + size_value_field_ = new views::Textfield; + views::Label* last_modified_label = new views::Label( + l10n_util::GetString(IDS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL)); + last_modified_value_field_ = new views::Textfield; + + using views::GridLayout; + + GridLayout* layout = new GridLayout(this); + layout->SetInsets(kDatabaseInfoViewInsetSize, + kDatabaseInfoViewInsetSize, + kDatabaseInfoViewInsetSize, + kDatabaseInfoViewInsetSize); + SetLayoutManager(layout); + + int three_column_layout_id = 0; + views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id); + column_set->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + + layout->StartRow(0, three_column_layout_id); + layout->AddView(description_label); + layout->AddView(description_value_field_); + layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); + layout->StartRow(0, three_column_layout_id); + layout->AddView(size_label); + layout->AddView(size_value_field_); + layout->AddPaddingRow(0, kRelatedControlSmallVerticalSpacing); + layout->StartRow(0, three_column_layout_id); + layout->AddView(last_modified_label); + layout->AddView(last_modified_value_field_); + + // Color these borderless text areas the same as the containing dialog. + SkColor text_area_background = color_utils::GetSysSkColor(COLOR_3DFACE); + // Now that the Textfields are in the view hierarchy, we can initialize them. + description_value_field_->SetReadOnly(true); + description_value_field_->RemoveBorder(); + description_value_field_->SetBackgroundColor(text_area_background); + size_value_field_->SetReadOnly(true); + size_value_field_->RemoveBorder(); + size_value_field_->SetBackgroundColor(text_area_background); + last_modified_value_field_->SetReadOnly(true); + last_modified_value_field_->RemoveBorder(); + last_modified_value_field_->SetBackgroundColor(text_area_background); +} diff --git a/chrome/browser/views/database_info_view.h b/chrome/browser/views/database_info_view.h new file mode 100755 index 0000000..a3b6743 --- /dev/null +++ b/chrome/browser/views/database_info_view.h @@ -0,0 +1,57 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_DATABASE_INFO_VIEW_H_ +#define CHROME_BROWSER_VIEWS_DATABASE_INFO_VIEW_H_ + +#include <string> +#include <vector> + +#include "views/view.h" +#include "chrome/browser/browsing_data_database_helper.h" + +namespace views { +class Label; +class Textfield; +} + +/////////////////////////////////////////////////////////////////////////////// +// DatabaseInfoView +// +// Responsible for displaying a tabular grid of Database information. +class DatabaseInfoView : public views::View { + public: + DatabaseInfoView(); + virtual ~DatabaseInfoView(); + + // Update the display from the specified Database info. + void SetDatabaseInfo( + const BrowsingDataDatabaseHelper::DatabaseInfo& database_info); + + // Clears the cookie display to indicate that no or multiple databases are + // selected. + void ClearDatabaseDisplay(); + + // Enables or disables the database property text fields. + void EnableDatabaseDisplay(bool enabled); + + protected: + // views::View overrides: + virtual void ViewHierarchyChanged( + bool is_add, views::View* parent, views::View* child); + + private: + // Set up the view layout. + void Init(); + + // Individual property labels. + views::Textfield* description_value_field_; + views::Textfield* size_value_field_; + views::Textfield* last_modified_value_field_; + + DISALLOW_COPY_AND_ASSIGN(DatabaseInfoView); +}; + + +#endif // CHROME_BROWSER_VIEWS_DATABASE_INFO_VIEW_H_ diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc index 3e80cf1..bcfa0a20 100644 --- a/chrome/browser/views/options/cookies_view.cc +++ b/chrome/browser/views/options/cookies_view.cc @@ -15,6 +15,7 @@ #include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/profile.h" #include "chrome/browser/views/cookie_info_view.h" +#include "chrome/browser/views/database_info_view.h" #include "chrome/browser/views/local_storage_info_view.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -92,7 +93,7 @@ void CookiesView::ButtonPressed( if (cookies_tree_model_->GetRoot()->GetChildCount() == 0) UpdateForEmptyState(); } else if (sender == remove_all_button_) { - cookies_tree_model_->DeleteAllCookies(); + cookies_tree_model_->DeleteAllStoredObjects(); UpdateForEmptyState(); } else if (sender == clear_search_button_) { ResetSearchQuery(); @@ -184,6 +185,10 @@ void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { cookie_info_view_->SetCookie(detailed_info.cookie->first, detailed_info.cookie->second); } else if (detailed_info.node_type == + CookieTreeNode::DetailedInfo::TYPE_DATABASE) { + UpdateVisibleDetailedInfo(database_info_view_); + database_info_view_->SetDatabaseInfo(*detailed_info.database_info); + } else if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { UpdateVisibleDetailedInfo(local_storage_info_view_); local_storage_info_view_->SetLocalStorageInfo( @@ -210,6 +215,7 @@ CookiesView::CookiesView(Profile* profile) description_label_(NULL), cookies_tree_(NULL), cookie_info_view_(NULL), + database_info_view_(NULL), local_storage_info_view_(NULL), remove_button_(NULL), remove_all_button_(NULL), @@ -237,9 +243,11 @@ void CookiesView::Init() { description_label_ = new views::Label( l10n_util::GetString(IDS_COOKIES_INFO_LABEL)); description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - cookies_tree_model_.reset(new CookiesTreeModel( - profile_, new BrowsingDataLocalStorageHelper(profile_))); + cookies_tree_model_.reset(new CookiesTreeModel(profile_, + new BrowsingDataDatabaseHelper(profile_), + new BrowsingDataLocalStorageHelper(profile_))); cookie_info_view_ = new CookieInfoView(false); + database_info_view_ = new DatabaseInfoView; local_storage_info_view_ = new LocalStorageInfoView; cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); remove_button_ = new views::NativeButton( @@ -291,6 +299,9 @@ void CookiesView::Init() { layout->AddView(cookie_info_view_, 1, 2); layout->StartRow(0, single_column_layout_id); + layout->AddView(database_info_view_); + + layout->StartRow(0, single_column_layout_id); layout->AddView(local_storage_info_view_); // Add the Remove/Remove All buttons to the ClientView @@ -318,7 +329,10 @@ void CookiesView::UpdateForEmptyState() { void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { view->SetVisible(true); - views::View* other = local_storage_info_view_; - if (view == local_storage_info_view_) other = cookie_info_view_; - other->SetVisible(false); + if (view != cookie_info_view_) + cookie_info_view_->SetVisible(false); + if (view != database_info_view_) + database_info_view_->SetVisible(false); + if (view != local_storage_info_view_) + local_storage_info_view_->SetVisible(false); } diff --git a/chrome/browser/views/options/cookies_view.h b/chrome/browser/views/options/cookies_view.h index 070120e..0010fbc 100644 --- a/chrome/browser/views/options/cookies_view.h +++ b/chrome/browser/views/options/cookies_view.h @@ -8,7 +8,6 @@ #include <string> #include "base/task.h" -#include "chrome/browser/browsing_data_local_storage_helper.h" #include "net/base/cookie_monster.h" #include "views/controls/button/button.h" #include "views/controls/tree/tree_view.h" @@ -25,10 +24,10 @@ class NativeButton; } // namespace views -class BrowsingDataLocalStorageHelper; class CookieInfoView; class CookiesTreeModel; class CookiesTreeView; +class DatabaseInfoView; class LocalStorageInfoView; class Profile; class Timer; @@ -102,6 +101,9 @@ class CookiesView : public views::View, // Update the UI when a cookie is selected. void UpdateForCookieState(); + // Update the UI when a database is selected. + void UpdateForDatabaseState(); + // Update the UI when a local storage is selected. void UpdateForLocalStorageState(); @@ -115,6 +117,7 @@ class CookiesView : public views::View, views::Label* description_label_; CookiesTreeView* cookies_tree_; CookieInfoView* cookie_info_view_; + DatabaseInfoView* database_info_view_; LocalStorageInfoView* local_storage_info_view_; views::NativeButton* remove_button_; views::NativeButton* remove_all_button_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 9a47575..f0ef2a1 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -230,6 +230,8 @@ 'browser/browser_url_handler.cc', 'browser/browser_url_handler.h', 'browser/browser_window.h', + 'browser/browsing_data_database_helper.cc', + 'browser/browsing_data_database_helper.h', 'browser/browsing_data_local_storage_helper.cc', 'browser/browsing_data_local_storage_helper.h', 'browser/browsing_data_remover.cc', @@ -1811,6 +1813,8 @@ 'browser/views/cookie_prompt_view.h', 'browser/views/create_application_shortcut_view.cc', 'browser/views/create_application_shortcut_view.h', + 'browser/views/database_info_view.cc', + 'browser/views/database_info_view.h', 'browser/views/detachable_toolbar_view.cc', 'browser/views/detachable_toolbar_view.h', 'browser/views/dialog_stubs_gtk.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index cf2a16b..f79e392 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -64,8 +64,10 @@ # The only thing used from browser is Browser::Type. 'browser/browser.h', 'browser/cocoa/browser_test_helper.h', + 'browser/mock_browsing_data_database_helper.h', + 'browser/mock_browsing_data_database_helper.cc', 'browser/mock_browsing_data_local_storage_helper.h', - 'browser/mock_browsing_data_local_storage_helper.cc', + 'browser/mock_browsing_data_local_storage_helper.cc', # TODO: these should live here but are currently used by # production code code in libbrowser (in chrome.gyp). #'browser/net/url_request_mock_http_job.cc', |