diff options
-rw-r--r-- | chrome/browser/browsing_data_file_system_helper.cc | 1 | ||||
-rw-r--r-- | chrome/browser/browsing_data_remover.cc | 101 | ||||
-rw-r--r-- | chrome/browser/browsing_data_remover.h | 11 | ||||
-rw-r--r-- | chrome/browser/browsing_data_remover_unittest.cc | 157 | ||||
-rw-r--r-- | chrome/test/testing_profile.cc | 5 | ||||
-rw-r--r-- | chrome/test/testing_profile.h | 12 | ||||
-rw-r--r-- | webkit/fileapi/file_system_file_util.h | 16 | ||||
-rw-r--r-- | webkit/fileapi/local_file_system_file_util.h | 6 | ||||
-rw-r--r-- | webkit/fileapi/obfuscated_file_system_file_util.h | 1 |
9 files changed, 250 insertions, 60 deletions
diff --git a/chrome/browser/browsing_data_file_system_helper.cc b/chrome/browser/browsing_data_file_system_helper.cc index 1c61cf3..4e3fea9 100644 --- a/chrome/browser/browsing_data_file_system_helper.cc +++ b/chrome/browser/browsing_data_file_system_helper.cc @@ -109,7 +109,6 @@ void BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread() { scoped_ptr<fileapi::SandboxMountPointProvider::OriginEnumerator> origin_enumerator(profile_->GetFileSystemContext()->path_manager()-> sandbox_provider()->CreateOriginEnumerator()); - // We don't own this pointer; deleting it would be a bad idea. fileapi::FileSystemQuotaUtil* quota_util = profile_-> GetFileSystemContext()->GetQuotaUtil(fileapi::kFileSystemTypeTemporary); diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc index e1de6f6..ed9b014 100644 --- a/chrome/browser/browsing_data_remover.cc +++ b/chrome/browser/browsing_data_remover.cc @@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/file_util.h" +#include "base/platform_file.h" #include "chrome/browser/autofill/personal_data_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_manager.h" @@ -42,6 +43,9 @@ #include "net/url_request/url_request_context_getter.h" #include "webkit/database/database_tracker.h" #include "webkit/database/database_util.h" +#include "webkit/fileapi/file_system_context.h" +#include "webkit/fileapi/file_system_operation_context.h" +#include "webkit/fileapi/sandbox_mount_point_provider.h" // Done so that we can use PostTask on BrowsingDataRemovers and not have // BrowsingDataRemover implement RefCounted. @@ -74,7 +78,8 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile, waiting_for_clear_networking_history_(false), waiting_for_clear_cache_(false), waiting_for_clear_appcache_(false), - waiting_for_clear_gears_data_(false) { + waiting_for_clear_gears_data_(false), + waiting_for_clear_file_systems_(false) { DCHECK(profile); } @@ -104,7 +109,8 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile, waiting_for_clear_cache_(false), waiting_for_clear_appcache_(false), waiting_for_clear_lso_data_(false), - waiting_for_clear_gears_data_(false) { + waiting_for_clear_gears_data_(false), + waiting_for_clear_file_systems_(false) { DCHECK(profile); } @@ -177,17 +183,22 @@ void BrowsingDataRemover::Remove(int remove_mask) { if (remove_mask & REMOVE_COOKIES) { UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies")); // Since we are running on the UI thread don't call GetURLRequestContext(). - net::CookieMonster* cookie_monster = - profile_->GetRequestContext()->DONTUSEME_GetCookieStore()-> - GetCookieMonster(); + net::CookieMonster* cookie_monster = NULL; + net::URLRequestContextGetter* rq_context = profile_->GetRequestContext(); + if (rq_context) { + cookie_monster = rq_context->DONTUSEME_GetCookieStore()-> + GetCookieMonster(); + } if (cookie_monster) cookie_monster->DeleteAllCreatedBetween(delete_begin_, delete_end_, true); // REMOVE_COOKIES is actually "cookies and other site data" so we make sure - // to remove other data such local databases, STS state, etc. - // We assume the end time is now. - - profile_->GetWebKitContext()->DeleteDataModifiedSince(delete_begin_); + // to remove other data such local databases, STS state, etc. These only can + // be removed if a WEBKIT thread exists, so check that first: + if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT)) { + // We assume the end time is now. + profile_->GetWebKitContext()->DeleteDataModifiedSince(delete_begin_); + } database_tracker_ = profile_->GetDatabaseTracker(); if (database_tracker_.get()) { @@ -214,14 +225,21 @@ void BrowsingDataRemover::Remove(int remove_mask) { &BrowsingDataRemover::ClearGearsDataOnFILEThread, profile_->GetPath())); - // TODO(michaeln): delete temporary file system data too - + waiting_for_clear_file_systems_ = true; BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, + BrowserThread::FILE, FROM_HERE, NewRunnableMethod( - profile_->GetTransportSecurityState(), - &net::TransportSecurityState::DeleteSince, - delete_begin_)); + this, + &BrowsingDataRemover::ClearFileSystemsOnFILEThread)); + + if (profile_->GetTransportSecurityState()) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + profile_->GetTransportSecurityState(), + &net::TransportSecurityState::DeleteSince, + delete_begin_)); + } } if (remove_mask & REMOVE_PASSWORDS) { @@ -485,9 +503,14 @@ void BrowsingDataRemover::ClearAppCacheOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(waiting_for_clear_appcache_); appcache_info_ = new appcache::AppCacheInfoCollection; - GetAppCacheService()->GetAllAppCacheInfo( - appcache_info_, &appcache_got_info_callback_); - // continues in OnGotAppCacheInfo + if (GetAppCacheService()) { + GetAppCacheService()->GetAllAppCacheInfo( + appcache_info_, &appcache_got_info_callback_); + // continues in OnGotAppCacheInfo + } else { + // Couldn't get app cache service, nothing to clear. + OnClearedAppCache(); + } } void BrowsingDataRemover::OnGotAppCacheInfo(int rv) { @@ -522,13 +545,49 @@ void BrowsingDataRemover::OnAppCacheDeleted(int rv) { ChromeAppCacheService* BrowsingDataRemover::GetAppCacheService() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ChromeURLRequestContext* request_context = - reinterpret_cast<ChromeURLRequestContext*>( - main_context_getter_->GetURLRequestContext()); + ChromeURLRequestContext* request_context = NULL; + if (main_context_getter_) + request_context = reinterpret_cast<ChromeURLRequestContext*>( + main_context_getter_->GetURLRequestContext()); return request_context ? request_context->appcache_service() : NULL; } +void BrowsingDataRemover::ClearFileSystemsOnFILEThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(waiting_for_clear_file_systems_); + scoped_refptr<fileapi::FileSystemContext> + fs_context(profile_->GetFileSystemContext()); + scoped_ptr<fileapi::SandboxMountPointProvider::OriginEnumerator> + origin_enumerator(fs_context->path_manager()->sandbox_provider()-> + CreateOriginEnumerator()); + + GURL origin; + while (!(origin = origin_enumerator->Next()).is_empty()) { + if (special_storage_policy_->IsStorageProtected(origin)) + continue; + if (delete_begin_ == base::Time()) { + // If the user chooses to delete browsing data "since the beginning of + // time" remove both temporary and persistent file systems entirely. + fs_context->DeleteDataForOriginAndTypeOnFileThread(origin, + fileapi::kFileSystemTypeTemporary); + fs_context->DeleteDataForOriginAndTypeOnFileThread(origin, + fileapi::kFileSystemTypePersistent); + } + // TODO(mkwst): Else? Decide what to do for time-based deletion: crbug/63700 + } + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, &BrowsingDataRemover::OnClearedFileSystems)); +} + +void BrowsingDataRemover::OnClearedFileSystems() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + waiting_for_clear_file_systems_ = false; + NotifyAndDeleteIfDone(); +} + // static void BrowsingDataRemover::ClearGearsData(const FilePath& profile_dir) { FilePath plugin_data = profile_dir.AppendASCII("Plugin Data"); diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h index 3f31a4d..06effca 100644 --- a/chrome/browser/browsing_data_remover.h +++ b/chrome/browser/browsing_data_remover.h @@ -149,6 +149,13 @@ class BrowsingDataRemover : public NotificationObserver, // Invoked on the FILE thread to delete HTML5 databases. void ClearDatabasesOnFILEThread(); + // Callback when HTML5 file systems have been cleared. Invokes + // NotifyAndDeleteIfDone. + void OnClearedFileSystems(); + + // Invoked on the FILE thread to delete HTML5 file systems. + void ClearFileSystemsOnFILEThread(); + // Callback when the appcache has been cleared. Invokes // NotifyAndDeleteIfDone. void OnClearedAppCache(); @@ -176,7 +183,8 @@ class BrowsingDataRemover : public NotificationObserver, !waiting_for_clear_history_ && !waiting_for_clear_networking_history_ && !waiting_for_clear_databases_ && !waiting_for_clear_appcache_ && - !waiting_for_clear_lso_data_ && !waiting_for_clear_gears_data_; + !waiting_for_clear_lso_data_ && !waiting_for_clear_gears_data_ && + !waiting_for_clear_file_systems_; } NotificationRegistrar registrar_; @@ -228,6 +236,7 @@ class BrowsingDataRemover : public NotificationObserver, bool waiting_for_clear_appcache_; bool waiting_for_clear_lso_data_; bool waiting_for_clear_gears_data_; + bool waiting_for_clear_file_systems_; ObserverList<Observer> observer_list_; diff --git a/chrome/browser/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data_remover_unittest.cc index 0e2b599..e55e87b 100644 --- a/chrome/browser/browsing_data_remover_unittest.cc +++ b/chrome/browser/browsing_data_remover_unittest.cc @@ -5,12 +5,26 @@ #include "chrome/browser/browsing_data_remover.h" #include "base/message_loop.h" +#include "base/platform_file.h" #include "chrome/browser/history/history.h" #include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/file_system_context.h" +#include "webkit/fileapi/file_system_operation_context.h" +#include "webkit/fileapi/file_system_file_util.h" +#include "webkit/fileapi/file_system_path_manager.h" +#include "webkit/fileapi/sandbox_mount_point_provider.h" namespace { +const char kTestkOrigin1[] = "http://host1:1/"; +const char kTestkOrigin2[] = "http://host2:1/"; +const char kTestkOrigin3[] = "http://host3:1/"; + +const GURL kOrigin1(kTestkOrigin1); +const GURL kOrigin2(kTestkOrigin2); +const GURL kOrigin3(kTestkOrigin3); + class BrowsingDataRemoverTester : public BrowsingDataRemover::Observer { public: BrowsingDataRemoverTester() {} @@ -79,16 +93,98 @@ class RemoveHistoryTester : public BrowsingDataRemoverTester { DISALLOW_COPY_AND_ASSIGN(RemoveHistoryTester); }; +class RemoveFileSystemTester : public BrowsingDataRemoverTester { + public: + explicit RemoveFileSystemTester() {} + + void FindFileSystemPathCallback(bool success, + const FilePath& path, + const std::string& name) { + found_file_system_ = success; + Notify(); + } + + bool FileSystemContainsOriginAndType(const GURL& origin, + fileapi::FileSystemType type) { + sandbox_->ValidateFileSystemRootAndGetURL( + origin, type, false, NewCallback(this, + &RemoveFileSystemTester::FindFileSystemPathCallback)); + BlockUntilNotified(); + return found_file_system_; + } + + virtual void PopulateTestFileSystemData(TestingProfile* profile) { + // Set up kOrigin1 with a temporary file system, kOrigin2 with a persistent + // file system, and kOrigin3 with both. + sandbox_ = profile->GetFileSystemContext()->path_manager()-> + sandbox_provider(); + + CreateDirectoryForOriginAndType(kOrigin1, + fileapi::kFileSystemTypeTemporary); + CreateDirectoryForOriginAndType(kOrigin2, + fileapi::kFileSystemTypePersistent); + CreateDirectoryForOriginAndType(kOrigin3, + fileapi::kFileSystemTypeTemporary); + CreateDirectoryForOriginAndType(kOrigin3, + fileapi::kFileSystemTypePersistent); + + EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin1, + fileapi::kFileSystemTypePersistent)); + EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin1, + fileapi::kFileSystemTypeTemporary)); + EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin2, + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin2, + fileapi::kFileSystemTypeTemporary)); + EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, + fileapi::kFileSystemTypePersistent)); + EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, + fileapi::kFileSystemTypeTemporary)); + } + + void CreateDirectoryForOriginAndType(const GURL& origin, + fileapi::FileSystemType type) { + FilePath target = sandbox_->ValidateFileSystemRootAndGetPathOnFileThread( + origin, type, FilePath(), true); + EXPECT_TRUE(file_util::DirectoryExists(target)); + } + + private: + fileapi::SandboxMountPointProvider* sandbox_; + bool found_file_system_; + + DISALLOW_COPY_AND_ASSIGN(RemoveFileSystemTester); +}; + class BrowsingDataRemoverTest : public testing::Test { public: - BrowsingDataRemoverTest() {} - virtual ~BrowsingDataRemoverTest() {} + BrowsingDataRemoverTest() + : ui_thread_(BrowserThread::UI, &message_loop_), + db_thread_(BrowserThread::DB, &message_loop_), + webkit_thread_(BrowserThread::WEBKIT, &message_loop_), + file_thread_(BrowserThread::FILE, &message_loop_), + io_thread_(BrowserThread::IO, &message_loop_), + profile_(new TestingProfile()) { + } + + virtual ~BrowsingDataRemoverTest() { + } + + void TearDown() { + // TestingProfile contains a WebKitContext. WebKitContext's destructor + // posts a message to the WEBKIT thread to delete some of its member + // variables. We need to ensure that the profile is destroyed, and that + // the message loop is cleared out, before destroying the threads and loop. + // Otherwise we leak memory. + profile_.reset(); + message_loop_.RunAllPending(); + } void BlockUntilBrowsingDataRemoved(BrowsingDataRemover::TimePeriod period, base::Time delete_end, int remove_mask, BrowsingDataRemoverTester* tester) { - BrowsingDataRemover* remover = new BrowsingDataRemover(&profile_, + BrowsingDataRemover* remover = new BrowsingDataRemover(profile_.get(), period, delete_end); remover->AddObserver(tester); @@ -98,13 +194,19 @@ class BrowsingDataRemoverTest : public testing::Test { } TestingProfile* GetProfile() { - return &profile_; + return profile_.get(); } private: - // message_loop_ must be defined before profile_ to prevent explosions. + // message_loop_, as well as all the threads associated with it must be + // defined before profile_ to prevent explosions. Oh how I love C++. MessageLoopForUI message_loop_; - TestingProfile profile_; + BrowserThread ui_thread_; + BrowserThread db_thread_; + BrowserThread webkit_thread_; + BrowserThread file_thread_; + BrowserThread io_thread_; + scoped_ptr<TestingProfile> profile_; DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverTest); }; @@ -113,14 +215,13 @@ TEST_F(BrowsingDataRemoverTest, RemoveHistoryForever) { scoped_ptr<RemoveHistoryTester> tester( new RemoveHistoryTester(GetProfile())); - GURL test_url("http://example.com/"); - tester->AddHistory(test_url, base::Time::Now()); - ASSERT_TRUE(tester->HistoryContainsURL(test_url)); + tester->AddHistory(kOrigin1, base::Time::Now()); + ASSERT_TRUE(tester->HistoryContainsURL(kOrigin1)); BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING, base::Time::Now(), BrowsingDataRemover::REMOVE_HISTORY, tester.get()); - EXPECT_FALSE(tester->HistoryContainsURL(test_url)); + EXPECT_FALSE(tester->HistoryContainsURL(kOrigin1)); } TEST_F(BrowsingDataRemoverTest, RemoveHistoryForLastHour) { @@ -129,18 +230,38 @@ TEST_F(BrowsingDataRemoverTest, RemoveHistoryForLastHour) { base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2); - GURL test_url1("http://example.com/1"); - GURL test_url2("http://example.com/2"); - tester->AddHistory(test_url1, base::Time::Now()); - tester->AddHistory(test_url2, two_hours_ago); - ASSERT_TRUE(tester->HistoryContainsURL(test_url1)); - ASSERT_TRUE(tester->HistoryContainsURL(test_url2)); + tester->AddHistory(kOrigin1, base::Time::Now()); + tester->AddHistory(kOrigin2, two_hours_ago); + ASSERT_TRUE(tester->HistoryContainsURL(kOrigin1)); + ASSERT_TRUE(tester->HistoryContainsURL(kOrigin2)); BlockUntilBrowsingDataRemoved(BrowsingDataRemover::LAST_HOUR, base::Time::Now(), BrowsingDataRemover::REMOVE_HISTORY, tester.get()); - EXPECT_FALSE(tester->HistoryContainsURL(test_url1)); - EXPECT_TRUE(tester->HistoryContainsURL(test_url2)); + EXPECT_FALSE(tester->HistoryContainsURL(kOrigin1)); + EXPECT_TRUE(tester->HistoryContainsURL(kOrigin2)); +} + +TEST_F(BrowsingDataRemoverTest, RemoveFileSystemsForever) { + scoped_ptr<RemoveFileSystemTester> tester(new RemoveFileSystemTester()); + + tester->PopulateTestFileSystemData(GetProfile()); + + BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING, + base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get()); + + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin1, + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin1, + fileapi::kFileSystemTypeTemporary)); + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin2, + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin2, + fileapi::kFileSystemTypeTemporary)); + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin3, + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin3, + fileapi::kFileSystemTypeTemporary)); } } // namespace diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index 1b4fd63..1b6cd7b 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -181,6 +181,7 @@ TestingProfile::~TestingProfile() { if (extension_service_.get()) { extension_service_.reset(); } + if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); } @@ -425,9 +426,9 @@ ExtensionEventRouter* TestingProfile::GetExtensionEventRouter() { ExtensionSpecialStoragePolicy* TestingProfile::GetExtensionSpecialStoragePolicy() { - if (!extension_special_storage_policy_) + if (!extension_special_storage_policy_.get()) extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(); - return extension_special_storage_policy_; + return extension_special_storage_policy_.get(); } SSLHostState* TestingProfile::GetSSLHostState() { diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index 51306a2..2083bea 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -352,13 +352,17 @@ class TestingProfile : public Profile { // Did the last session exit cleanly? Default is true. bool last_session_exited_cleanly_; - // The main database tracker for this profile. - // Should be used only on the file thread. - scoped_refptr<webkit_database::DatabaseTracker> db_tracker_; + + // FileSystemContext. Created lazily by GetFileSystemContext(). + scoped_refptr<fileapi::FileSystemContext> file_system_context_; // WebKitContext, lazily initialized by GetWebKitContext(). scoped_refptr<WebKitContext> webkit_context_; + // The main database tracker for this profile. + // Should be used only on the file thread. + scoped_refptr<webkit_database::DatabaseTracker> db_tracker_; + scoped_refptr<HostContentSettingsMap> host_content_settings_map_; scoped_refptr<GeolocationContentSettingsMap> geolocation_content_settings_map_; @@ -381,8 +385,6 @@ class TestingProfile : public Profile { scoped_refptr<ExtensionSpecialStoragePolicy> extension_special_storage_policy_; - // FileSystemContext. Created lazily by GetFileSystemContext(). - scoped_refptr<fileapi::FileSystemContext> file_system_context_; // The proxy prefs tracker. scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; diff --git a/webkit/fileapi/file_system_file_util.h b/webkit/fileapi/file_system_file_util.h index d6b72e6..f489490 100644 --- a/webkit/fileapi/file_system_file_util.h +++ b/webkit/fileapi/file_system_file_util.h @@ -230,6 +230,14 @@ class FileSystemFileUtil { virtual bool IsDirectory() { return false; } }; + // Returns a pointer to a new instance of AbstractFileEnumerator which is + // implemented for each FileUtil subclass. The instance needs to be freed + // by the caller, and its lifetime should not extend past when the current + // call returns to the main FILE message loop. + virtual AbstractFileEnumerator* CreateFileEnumerator( + FileSystemOperationContext* unused, + const FilePath& root_path); + protected: FileSystemFileUtil() { } @@ -272,14 +280,6 @@ class FileSystemFileUtil { const FilePath& dest_file_path, bool copy); - // Returns a pointer to a new instance of AbstractFileEnumerator which is - // implemented for each FileUtil subclass. The instance needs to be freed - // by the caller, and its lifetime should not extend past when the current - // call returns to the main FILE message loop. - virtual AbstractFileEnumerator* CreateFileEnumerator( - FileSystemOperationContext* unused, - const FilePath& root_path); - friend struct DefaultSingletonTraits<FileSystemFileUtil>; DISALLOW_COPY_AND_ASSIGN(FileSystemFileUtil); }; diff --git a/webkit/fileapi/local_file_system_file_util.h b/webkit/fileapi/local_file_system_file_util.h index a7af395..8b18f68 100644 --- a/webkit/fileapi/local_file_system_file_util.h +++ b/webkit/fileapi/local_file_system_file_util.h @@ -113,13 +113,13 @@ class LocalFileSystemFileUtil : public FileSystemFileUtil { FileSystemOperationContext* context, const FilePath& file_path); - protected: - LocalFileSystemFileUtil() { } - virtual AbstractFileEnumerator* CreateFileEnumerator( FileSystemOperationContext* context, const FilePath& root_path); + protected: + LocalFileSystemFileUtil() { } + friend struct DefaultSingletonTraits<LocalFileSystemFileUtil>; DISALLOW_COPY_AND_ASSIGN(LocalFileSystemFileUtil); diff --git a/webkit/fileapi/obfuscated_file_system_file_util.h b/webkit/fileapi/obfuscated_file_system_file_util.h index e69c49a..88caa65 100644 --- a/webkit/fileapi/obfuscated_file_system_file_util.h +++ b/webkit/fileapi/obfuscated_file_system_file_util.h @@ -172,7 +172,6 @@ class ObfuscatedFileSystemFileUtil : public FileSystemFileUtil, // object. AbstractOriginEnumerator* CreateOriginEnumerator(); - protected: virtual AbstractFileEnumerator* CreateFileEnumerator( FileSystemOperationContext* context, const FilePath& root_path) OVERRIDE; |