Update to Chromium revision 106500.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@329 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-10-20 20:34:13 +00:00
parent 7a07aaf5f1
commit 04c948fd51
14 changed files with 283 additions and 153 deletions

View File

@ -17,5 +17,5 @@
{ {
'chromium_url': 'http://src.chromium.org/svn/trunk/src', 'chromium_url': 'http://src.chromium.org/svn/trunk/src',
'chromium_revision': '105051', 'chromium_revision': '106500',
} }

View File

@ -267,8 +267,8 @@ class BrowserBackendProxy
status_result_ = appcache::UNCACHED; status_result_ = appcache::UNCACHED;
event_.Reset(); event_.Reset();
system_->io_message_loop()->PostTask( system_->io_message_loop()->PostTask(
FROM_HERE, FROM_HERE, base::IgnoreReturn<appcache::Status>(
NewRunnableMethod(this, &BrowserBackendProxy::GetStatus, host_id)); base::Bind(&BrowserBackendProxy::GetStatus, this, host_id)));
event_.Wait(); event_.Wait();
} else if (system_->is_io_thread()) { } else if (system_->is_io_thread()) {
system_->backend_impl_->GetStatusWithCallback( system_->backend_impl_->GetStatusWithCallback(
@ -284,8 +284,8 @@ class BrowserBackendProxy
bool_result_ = false; bool_result_ = false;
event_.Reset(); event_.Reset();
system_->io_message_loop()->PostTask( system_->io_message_loop()->PostTask(
FROM_HERE, FROM_HERE, base::IgnoreReturn<bool>(
NewRunnableMethod(this, &BrowserBackendProxy::StartUpdate, host_id)); base::Bind(&BrowserBackendProxy::StartUpdate, this, host_id)));
event_.Wait(); event_.Wait();
} else if (system_->is_io_thread()) { } else if (system_->is_io_thread()) {
system_->backend_impl_->StartUpdateWithCallback( system_->backend_impl_->StartUpdateWithCallback(
@ -301,8 +301,8 @@ class BrowserBackendProxy
bool_result_ = false; bool_result_ = false;
event_.Reset(); event_.Reset();
system_->io_message_loop()->PostTask( system_->io_message_loop()->PostTask(
FROM_HERE, FROM_HERE, base::IgnoreReturn<bool>(
NewRunnableMethod(this, &BrowserBackendProxy::SwapCache, host_id)); base::Bind(&BrowserBackendProxy::SwapCache, this, host_id)));
event_.Wait(); event_.Wait();
} else if (system_->is_io_thread()) { } else if (system_->is_io_thread()) {
system_->backend_impl_->SwapCacheWithCallback( system_->backend_impl_->SwapCacheWithCallback(

View File

@ -236,7 +236,7 @@ void BrowserDragDelegate::PrepareDragForFileContents(
if (file_name.value().empty()) { if (file_name.value().empty()) {
// Retrieve the name from the URL. // Retrieve the name from the URL.
file_name = FilePath( file_name = FilePath(
net::GetSuggestedFilename(drop_data.url, "", "", "", "", string16())); net::GetSuggestedFilename(drop_data.url, "", "", "", "", ""));
if (file_name.value().size() + drop_data.file_extension.size() + 1 > if (file_name.value().size() + drop_data.file_extension.size() + 1 >
MAX_PATH) { MAX_PATH) {
file_name = FilePath(file_name.value().substr( file_name = FilePath(file_name.value().substr(

View File

@ -1,4 +1,5 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -6,6 +7,9 @@
#include "cef_thread.h" #include "cef_thread.h"
#include <list> #include <list>
#include <map>
#include <set>
#include <utility>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/bind.h" #include "base/bind.h"
@ -16,9 +20,11 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
#include "net/base/registry_controlled_domain.h"
#include "sql/meta_table.h" #include "sql/meta_table.h"
#include "sql/statement.h" #include "sql/statement.h"
#include "sql/transaction.h" #include "sql/transaction.h"
@ -26,10 +32,24 @@
using base::Time; using base::Time;
// This class is designed to be shared between any calling threads and the // This class is designed to be shared between any calling threads and the
// database thread. It batches operations and commits them on a timer. // database thread. It batches operations and commits them on a timer.
// This class expects to be Load()'ed once on any thread. Loading occurs //
// asynchronously on the DB thread and the caller will be notified on the IO // BrowserPersistentCookieStore::Load is called to load all cookies. It
// thread. Subsequent to loading, mutations may be queued by any thread using // delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
// task to the DB thread. This task calls Backend::ChainLoadCookies(), which
// repeatedly posts itself to the DB thread to load each eTLD+1's cookies in
// separate tasks. When this is complete, Backend::NotifyOnIOThread is posted
// to the IO thread, which notifies the caller of BrowserPersistentCookieStore::
// Load that the load is complete.
//
// If a priority load request is invoked via BrowserPersistentCookieStore::
// LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
// Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just
// that single domain key (eTLD+1)'s cookies, and posts a Backend::
// NotifyOnIOThread to the IO thread to notify the caller of
// BrowserPersistentCookieStore::LoadCookiesForKey that that load is complete.
//
// Subsequent to loading, mutations may be queued by any thread using
// AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to // AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
// disk on the DB thread every 30 seconds, 512 operations, or call to Flush(), // disk on the DB thread every 30 seconds, 512 operations, or call to Flush(),
// whichever occurs first. // whichever occurs first.
@ -40,11 +60,16 @@ class BrowserPersistentCookieStore::Backend
: path_(path), : path_(path),
db_(NULL), db_(NULL),
num_pending_(0), num_pending_(0),
clear_local_state_on_exit_(false) { clear_local_state_on_exit_(false),
initialized_(false) {
} }
// Creates or load the SQLite database. // Creates or loads the SQLite database.
bool Load(const LoadedCallback& loaded_callback); void Load(const LoadedCallback& loaded_callback);
// Loads cookies for the domain key (eTLD+1).
void LoadCookiesForKey(const std::string& domain,
const LoadedCallback& loaded_callback);
// Batch a cookie addition. // Batch a cookie addition.
void AddCookie(const net::CookieMonster::CanonicalCookie& cc); void AddCookie(const net::CookieMonster::CanonicalCookie& cc);
@ -97,17 +122,30 @@ class BrowserPersistentCookieStore::Backend
}; };
private: private:
// Creates or load the SQLite database on DB thread. // Creates or loads the SQLite database on DB thread.
void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback); void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback);
// Notify the CookieMonster when loading complete.
// Loads cookies for the domain key (eTLD+1) on DB thread.
void LoadKeyAndNotifyOnDBThread(const std::string& domains,
const LoadedCallback& loaded_callback);
// Notifies the CookieMonster when loading completes for a specific domain key
// or for all domain keys. Triggers the callback and passes it all cookies
// that have been loaded from DB since last IO notification.
void NotifyOnIOThread( void NotifyOnIOThread(
const LoadedCallback& loaded_callback, const LoadedCallback& loaded_callback,
bool load_success, bool load_success);
const std::vector<net::CookieMonster::CanonicalCookie*>& cookies);
// Initialize the data base. // Initialize the data base.
bool InitializeDatabase(); bool InitializeDatabase();
// Load cookies to the data base, and read cookies.
bool LoadInternal(std::vector<net::CookieMonster::CanonicalCookie*>* cookies); // Loads cookies for the next domain key from the DB, then either reschedules
// itself or schedules the provided callback to run on the IO thread (if all
// domains are loaded).
void ChainLoadCookies(const LoadedCallback& loaded_callback);
// Load all cookies for a set of domains/hosts
bool LoadCookiesForDomains(const std::set<std::string>& key);
// Batch a cookie operation (add or delete) // Batch a cookie operation (add or delete)
void BatchOperation(PendingOperation::OperationType op, void BatchOperation(PendingOperation::OperationType op,
@ -126,9 +164,21 @@ class BrowserPersistentCookieStore::Backend
PendingOperationsList::size_type num_pending_; PendingOperationsList::size_type num_pending_;
// True if the persistent store should be deleted upon destruction. // True if the persistent store should be deleted upon destruction.
bool clear_local_state_on_exit_; bool clear_local_state_on_exit_;
// Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|. // Guard |cookies_|, |pending_|, |num_pending_| and
// |clear_local_state_on_exit_|.
base::Lock lock_; base::Lock lock_;
// Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
// the number of messages sent to the IO thread. Sent back in response to
// individual load requests for domain keys or when all loading completes.
std::vector<net::CookieMonster::CanonicalCookie*> cookies_;
// Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB.
std::map<std::string, std::set<std::string> > keys_to_load_;
// Indicates if DB has been initialized.
bool initialized_;
DISALLOW_COPY_AND_ASSIGN(Backend); DISALLOW_COPY_AND_ASSIGN(Backend);
}; };
@ -166,43 +216,91 @@ bool InitTable(sql::Connection* db) {
// so we want those people to get it. Ignore errors, since it may exist. // so we want those people to get it. Ignore errors, since it may exist.
db->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies" db->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies"
" (creation_utc)"); " (creation_utc)");
db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)");
return true; return true;
} }
} // namespace } // namespace
bool BrowserPersistentCookieStore::Backend::Load( void BrowserPersistentCookieStore::Backend::Load(
const LoadedCallback& loaded_callback) { const LoadedCallback& loaded_callback) {
// This function should be called only once per instance. // This function should be called only once per instance.
DCHECK(!db_.get()); DCHECK(!db_.get());
CefThread::PostTask( CefThread::PostTask(
CefThread::FILE, FROM_HERE, CefThread::FILE, FROM_HERE,
base::Bind(&Backend::LoadAndNotifyOnDBThread, base::Unretained(this), base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback));
loaded_callback)); }
return true;
void BrowserPersistentCookieStore::Backend::LoadCookiesForKey(
const std::string& key,
const LoadedCallback& loaded_callback) {
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this,
key,
loaded_callback));
} }
void BrowserPersistentCookieStore::Backend::LoadAndNotifyOnDBThread( void BrowserPersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
const LoadedCallback& loaded_callback) { const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE)); DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
std::vector<net::CookieMonster::CanonicalCookie*> cookies;
bool load_success = LoadInternal(&cookies); if (!InitializeDatabase()) {
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, false));
} else {
ChainLoadCookies(loaded_callback);
}
}
CefThread::PostTask(CefThread::IO, FROM_HERE, base::Bind( void BrowserPersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
&BrowserPersistentCookieStore::Backend::NotifyOnIOThread, const std::string& key,
base::Unretained(this), loaded_callback, load_success, cookies)); const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
bool success = false;
if (InitializeDatabase()) {
std::map<std::string, std::set<std::string> >::iterator
it = keys_to_load_.find(key);
if (it != keys_to_load_.end()) {
success = LoadCookiesForDomains(it->second);
keys_to_load_.erase(it);
} else {
success = true;
}
}
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, success));
} }
void BrowserPersistentCookieStore::Backend::NotifyOnIOThread( void BrowserPersistentCookieStore::Backend::NotifyOnIOThread(
const LoadedCallback& loaded_callback, const LoadedCallback& loaded_callback,
bool load_success, bool load_success) {
const std::vector<net::CookieMonster::CanonicalCookie*>& cookies) {
DCHECK(CefThread::CurrentlyOn(CefThread::IO)); DCHECK(CefThread::CurrentlyOn(CefThread::IO));
std::vector<net::CookieMonster::CanonicalCookie*> cookies;
{
base::AutoLock locked(lock_);
cookies.swap(cookies_);
}
loaded_callback.Run(cookies); loaded_callback.Run(cookies);
} }
bool BrowserPersistentCookieStore::Backend::InitializeDatabase() { bool BrowserPersistentCookieStore::Backend::InitializeDatabase() {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
if (initialized_) {
return true;
}
const FilePath dir = path_.DirName(); const FilePath dir = path_.DirName();
if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
return false; return false;
@ -224,47 +322,108 @@ bool BrowserPersistentCookieStore::Backend::InitializeDatabase() {
} }
db_->Preload(); db_->Preload();
return true;
}
bool BrowserPersistentCookieStore::Backend::LoadInternal( // Retrieve all the domains
std::vector<net::CookieMonster::CanonicalCookie*>* cookies) {
if (!InitializeDatabase()) {
return false;
}
// Slurp all the cookies into the out-vector.
sql::Statement smt(db_->GetUniqueStatement( sql::Statement smt(db_->GetUniqueStatement(
"SELECT creation_utc, host_key, name, value, path, expires_utc, secure, " "SELECT DISTINCT host_key FROM cookies"));
"httponly, last_access_utc FROM cookies"));
if (!smt) { if (!smt) {
NOTREACHED() << "select statement prep failed"; NOTREACHED() << "select statement prep failed";
db_.reset(); db_.reset();
return false; return false;
} }
// Build a map of domain keys (always eTLD+1) to domains.
while (smt.Step()) { while (smt.Step()) {
scoped_ptr<net::CookieMonster::CanonicalCookie> cc( std::string domain = smt.ColumnString(0);
new net::CookieMonster::CanonicalCookie( std::string key =
// The "source" URL is not used with persisted cookies. net::RegistryControlledDomainService::GetDomainAndRegistry(domain);
GURL(), // Source
smt.ColumnString(2), // name std::map<std::string, std::set<std::string> >::iterator it =
smt.ColumnString(3), // value keys_to_load_.find(key);
smt.ColumnString(1), // domain if (it == keys_to_load_.end())
smt.ColumnString(4), // path it = keys_to_load_.insert(std::make_pair
std::string(), // TODO(abarth): Persist mac_key (key, std::set<std::string>())).first;
std::string(), // TODO(abarth): Persist mac_algorithm it->second.insert(domain);
Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
smt.ColumnInt(6) != 0, // secure
smt.ColumnInt(7) != 0, // httponly
true)); // has_expires
DLOG_IF(WARNING,
cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
cookies->push_back(cc.release());
} }
initialized_ = true;
return true;
}
void BrowserPersistentCookieStore::Backend::ChainLoadCookies(
const LoadedCallback& loaded_callback) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
bool load_success = true;
if (keys_to_load_.size() > 0) {
// Load cookies for the first domain key.
std::map<std::string, std::set<std::string> >::iterator
it = keys_to_load_.begin();
load_success = LoadCookiesForDomains(it->second);
keys_to_load_.erase(it);
}
// If load is successful and there are more domain keys to be loaded,
// then post a DB task to continue chain-load;
// Otherwise notify on IO thread.
if (load_success && keys_to_load_.size() > 0) {
CefThread::PostTask(
CefThread::FILE, FROM_HERE,
base::Bind(&Backend::ChainLoadCookies, this, loaded_callback));
} else {
CefThread::PostTask(
CefThread::IO, FROM_HERE,
base::Bind(&BrowserPersistentCookieStore::Backend::NotifyOnIOThread,
this, loaded_callback, load_success));
}
}
bool BrowserPersistentCookieStore::Backend::LoadCookiesForDomains(
const std::set<std::string>& domains) {
DCHECK(CefThread::CurrentlyOn(CefThread::FILE));
sql::Statement smt(db_->GetCachedStatement(SQL_FROM_HERE,
"SELECT creation_utc, host_key, name, value, path, expires_utc, secure, "
"httponly, last_access_utc FROM cookies WHERE host_key = ?"));
if (!smt) {
NOTREACHED() << "select statement prep failed";
db_.reset();
return false;
}
std::vector<net::CookieMonster::CanonicalCookie*> cookies;
std::set<std::string>::const_iterator it = domains.begin();
for (; it != domains.end(); ++it) {
smt.BindString(0, *it);
while (smt.Step()) {
scoped_ptr<net::CookieMonster::CanonicalCookie> cc(
new net::CookieMonster::CanonicalCookie(
// The "source" URL is not used with persisted cookies.
GURL(), // Source
smt.ColumnString(2), // name
smt.ColumnString(3), // value
smt.ColumnString(1), // domain
smt.ColumnString(4), // path
std::string(), // TODO(abarth): Persist mac_key
std::string(), // TODO(abarth): Persist mac_algorithm
Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
smt.ColumnInt(6) != 0, // secure
smt.ColumnInt(7) != 0, // httponly
true)); // has_expires
DLOG_IF(WARNING,
cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
cookies.push_back(cc.release());
}
smt.Reset();
}
{
base::AutoLock locked(lock_);
cookies_.insert(cookies_.end(), cookies.begin(), cookies.end());
}
return true; return true;
} }
@ -379,13 +538,13 @@ void BrowserPersistentCookieStore::Backend::BatchOperation(
if (num_pending == 1) { if (num_pending == 1) {
// We've gotten our first entry for this batch, fire off the timer. // We've gotten our first entry for this batch, fire off the timer.
CefThread::PostDelayedTask( CefThread::PostDelayedTask(
CefThread::FILE, FROM_HERE, CefThread::FILE, FROM_HERE,
NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs); NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs);
} else if (num_pending == kCommitAfterBatchSize) { } else if (num_pending == kCommitAfterBatchSize) {
// We've reached a big enough batch, fire off a commit now. // We've reached a big enough batch, fire off a commit now.
CefThread::PostTask( CefThread::PostTask(
CefThread::FILE, FROM_HERE, CefThread::FILE, FROM_HERE,
NewRunnableMethod(this, &Backend::Commit)); NewRunnableMethod(this, &Backend::Commit));
} }
} }
@ -531,8 +690,14 @@ BrowserPersistentCookieStore::~BrowserPersistentCookieStore() {
} }
} }
bool BrowserPersistentCookieStore::Load(const LoadedCallback& loaded_callback) { void BrowserPersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
return backend_->Load(loaded_callback); backend_->Load(loaded_callback);
}
void BrowserPersistentCookieStore::LoadCookiesForKey(
const std::string& key,
const LoadedCallback& loaded_callback) {
backend_->LoadCookiesForKey(key, loaded_callback);
} }
void BrowserPersistentCookieStore::AddCookie( void BrowserPersistentCookieStore::AddCookie(

View File

@ -1,5 +1,4 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Portions copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -17,10 +16,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "net/base/cookie_monster.h" #include "net/base/cookie_monster.h"
class FilePath; class FilePath;
class Task;
// Implements the PersistentCookieStore interface in terms of a SQLite database. // Implements the PersistentCookieStore interface in terms of a SQLite database.
// For documentation about the actual member functions consult the documentation // For documentation about the actual member functions consult the documentation
@ -31,7 +32,10 @@ class BrowserPersistentCookieStore
explicit BrowserPersistentCookieStore(const FilePath& path); explicit BrowserPersistentCookieStore(const FilePath& path);
virtual ~BrowserPersistentCookieStore(); virtual ~BrowserPersistentCookieStore();
virtual bool Load(const LoadedCallback& loaded_callback) OVERRIDE; virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
virtual void LoadCookiesForKey(const std::string& key,
const LoadedCallback& callback) OVERRIDE;
virtual void AddCookie( virtual void AddCookie(
const net::CookieMonster::CanonicalCookie& cc) OVERRIDE; const net::CookieMonster::CanonicalCookie& cc) OVERRIDE;

View File

@ -243,7 +243,7 @@ class RequestProxy : public net::URLRequest::Delegate,
webkit_glue::ShouldDownload(content_disposition, info.mime_type)) { webkit_glue::ShouldDownload(content_disposition, info.mime_type)) {
string16 filename = net::GetSuggestedFilename(url, string16 filename = net::GetSuggestedFilename(url,
content_disposition, info.charset, "", info.mime_type, content_disposition, info.charset, "", info.mime_type,
ASCIIToUTF16("download")); "download");
CefRefPtr<CefDownloadHandler> dl_handler; CefRefPtr<CefDownloadHandler> dl_handler;
if (handler->GetDownloadHandler(browser_, info.mime_type, if (handler->GetDownloadHandler(browser_, info.mime_type,
filename, info.content_length, filename, info.content_length,

View File

@ -4,36 +4,23 @@
#include "browser_webblobregistry_impl.h" #include "browser_webblobregistry_impl.h"
#include "base/bind.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/task.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBlobData.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBlobData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
#include "webkit/blob/blob_data.h" #include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_storage_controller.h" #include "webkit/blob/blob_storage_controller.h"
using WebKit::WebBlobData; using WebKit::WebBlobData;
using WebKit::WebString;
using WebKit::WebURL; using WebKit::WebURL;
using webkit_blob::BlobData;
namespace { namespace {
MessageLoop* g_io_thread; MessageLoop* g_io_thread;
webkit_blob::BlobStorageController* g_blob_storage_controller; webkit_blob::BlobStorageController* g_blob_storage_controller;
// WebURL contains a WebCString object that is ref-counted,
// but not thread-safe ref-counted.
// "Normal" copying of WebURL results in a copy that is not thread-safe.
// This method creates a deep copy of WebURL.
WebURL GetWebURLThreadsafeCopy(const WebURL& source) {
const WebKit::WebCString spec(source.spec().data(), source.spec().length());
const url_parse::Parsed& parsed(source.parsed());
const bool is_valid = source.isValid();
return WebURL(spec, parsed, is_valid);
}
} // namespace } // namespace
/* static */ /* static */
@ -55,70 +42,43 @@ BrowserWebBlobRegistryImpl::BrowserWebBlobRegistryImpl() {
void BrowserWebBlobRegistryImpl::registerBlobURL( void BrowserWebBlobRegistryImpl::registerBlobURL(
const WebURL& url, WebBlobData& data) { const WebURL& url, WebBlobData& data) {
DCHECK(g_io_thread); DCHECK(g_io_thread);
CancelableTask* task; GURL thread_safe_url = url; // WebURL uses refcounted strings.
{ g_io_thread->PostTask(FROM_HERE, base::Bind(
scoped_refptr<webkit_blob::BlobData> blob_data( &BrowserWebBlobRegistryImpl::AddFinishedBlob, this,
new webkit_blob::BlobData(data)); thread_safe_url, make_scoped_refptr(new BlobData(data))));
WebURL url_copy = GetWebURLThreadsafeCopy(url);
task =
NewRunnableMethod(
this, &BrowserWebBlobRegistryImpl::DoRegisterBlobUrl, url_copy,
blob_data);
// After this block exits, url_copy is disposed, and
// the underlying WebCString will have a refcount=1 and will
// only be accessible from the task object.
}
g_io_thread->PostTask(FROM_HERE, task);
} }
void BrowserWebBlobRegistryImpl::registerBlobURL( void BrowserWebBlobRegistryImpl::registerBlobURL(
const WebURL& url, const WebURL& src_url) { const WebURL& url, const WebURL& src_url) {
DCHECK(g_io_thread); DCHECK(g_io_thread);
CancelableTask* task; GURL thread_safe_url = url;
{ GURL thread_safe_src_url = src_url;
WebURL url_copy = GetWebURLThreadsafeCopy(url); g_io_thread->PostTask(FROM_HERE, base::Bind(
WebURL src_url_copy = GetWebURLThreadsafeCopy(src_url); &BrowserWebBlobRegistryImpl::CloneBlob, this,
task = thread_safe_url, thread_safe_src_url));
NewRunnableMethod(this,
&BrowserWebBlobRegistryImpl::DoRegisterBlobUrlFrom,
url_copy,
src_url_copy);
// After this block exits, url_copy and src_url_copy are disposed, and
// the underlying WebCStrings will have a refcount=1 and will
// only be accessible from the task object.
}
g_io_thread->PostTask(FROM_HERE, task);
} }
void BrowserWebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) { void BrowserWebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) {
DCHECK(g_io_thread); DCHECK(g_io_thread);
CancelableTask* task; GURL thread_safe_url = url;
{ g_io_thread->PostTask(FROM_HERE, base::Bind(
WebURL url_copy = GetWebURLThreadsafeCopy(url); &BrowserWebBlobRegistryImpl::RemoveBlob, this,
task = thread_safe_url));
NewRunnableMethod(this,
&BrowserWebBlobRegistryImpl::DoUnregisterBlobUrl,
url_copy);
// After this block exits, url_copy is disposed, and
// the underlying WebCString will have a refcount=1 and will
// only be accessible from the task object.
}
g_io_thread->PostTask(FROM_HERE, task);
} }
void BrowserWebBlobRegistryImpl::DoRegisterBlobUrl( void BrowserWebBlobRegistryImpl::AddFinishedBlob(
const GURL& url, webkit_blob::BlobData* blob_data) { const GURL& url, BlobData* blob_data) {
DCHECK(g_blob_storage_controller); DCHECK(g_blob_storage_controller);
g_blob_storage_controller->RegisterBlobUrl(url, blob_data); g_blob_storage_controller->AddFinishedBlob(url, blob_data);
} }
void BrowserWebBlobRegistryImpl::DoRegisterBlobUrlFrom( void BrowserWebBlobRegistryImpl::CloneBlob(
const GURL& url, const GURL& src_url) { const GURL& url, const GURL& src_url) {
DCHECK(g_blob_storage_controller); DCHECK(g_blob_storage_controller);
g_blob_storage_controller->RegisterBlobUrlFrom(url, src_url); g_blob_storage_controller->CloneBlob(url, src_url);
} }
void BrowserWebBlobRegistryImpl::DoUnregisterBlobUrl(const GURL& url) { void BrowserWebBlobRegistryImpl::RemoveBlob(const GURL& url) {
DCHECK(g_blob_storage_controller); DCHECK(g_blob_storage_controller);
g_blob_storage_controller->UnregisterBlobUrl(url); g_blob_storage_controller->RemoveBlob(url);
} }

View File

@ -1,4 +1,4 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -32,15 +32,14 @@ class BrowserWebBlobRegistryImpl
const WebKit::WebURL& src_url); const WebKit::WebURL& src_url);
virtual void unregisterBlobURL(const WebKit::WebURL& url); virtual void unregisterBlobURL(const WebKit::WebURL& url);
// Run on I/O thread. private:
void DoRegisterBlobUrl(const GURL& url, webkit_blob::BlobData* blob_data);
void DoRegisterBlobUrlFrom(const GURL& url, const GURL& src_url);
void DoUnregisterBlobUrl(const GURL& url);
protected:
friend class base::RefCountedThreadSafe<BrowserWebBlobRegistryImpl>; friend class base::RefCountedThreadSafe<BrowserWebBlobRegistryImpl>;
private: // Run on I/O thread.
void AddFinishedBlob(const GURL& url, webkit_blob::BlobData* blob_data);
void CloneBlob(const GURL& url, const GURL& src_url);
void RemoveBlob(const GURL& url);
DISALLOW_COPY_AND_ASSIGN(BrowserWebBlobRegistryImpl); DISALLOW_COPY_AND_ASSIGN(BrowserWebBlobRegistryImpl);
}; };

View File

@ -225,7 +225,7 @@ WebKit::WebGraphicsContext3D* BrowserWebKitInit::createGraphicsContext3D() {
return new webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl(); return new webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl();
} else { } else {
return new webkit::gpu::WebGraphicsContext3DInProcessImpl( return new webkit::gpu::WebGraphicsContext3DInProcessImpl(
gfx::kNullPluginWindow); gfx::kNullPluginWindow, NULL);
} }
} }

View File

@ -683,6 +683,7 @@ WebMediaPlayer* BrowserWebViewDelegate::createMediaPlayer(
scoped_ptr<webkit_glue::WebMediaPlayerImpl> result( scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
new webkit_glue::WebMediaPlayerImpl(client, new webkit_glue::WebMediaPlayerImpl(client,
NULL,
collection.release(), collection.release(),
message_loop_factory.release(), message_loop_factory.release(),
NULL, NULL,

View File

@ -8,6 +8,7 @@
#include <algorithm> #include <algorithm>
#include "base/bind.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/file_util.h" #include "base/file_util.h"
#include "base/string_util.h" #include "base/string_util.h"
@ -59,9 +60,9 @@ int64 DOMStorageContext::CloneSessionStorage(int64 original_id) {
DCHECK(!CefThread::CurrentlyOn(CefThread::UI)); DCHECK(!CefThread::CurrentlyOn(CefThread::UI));
int64 clone_id = AllocateSessionStorageNamespaceId(); int64 clone_id = AllocateSessionStorageNamespaceId();
CefThread::PostTask( CefThread::PostTask(
CefThread::UI, FROM_HERE, NewRunnableFunction( CefThread::UI, FROM_HERE,
&DOMStorageContext::CompleteCloningSessionStorage, base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this,
this, original_id, clone_id)); original_id, clone_id));
return clone_id; return clone_id;
} }

View File

@ -169,7 +169,7 @@ void GenerateFileName(const GURL& url,
referrer_charset, referrer_charset,
suggested_name, suggested_name,
mime_type, mime_type,
ASCIIToUTF16("download")); "download");
// TODO(evan): this code is totally wrong -- we should just generate // TODO(evan): this code is totally wrong -- we should just generate
// Unicode filenames and do all this encoding switching at the end. // Unicode filenames and do all this encoding switching at the end.

View File

@ -65,7 +65,7 @@ FilePath GetFileNameFromDragData(const WebDropData& drop_data) {
if (file_name.empty()) { if (file_name.empty()) {
// Retrieve the name from the URL. // Retrieve the name from the URL.
string16 suggested_filename = string16 suggested_filename =
net::GetSuggestedFilename(drop_data.url, "", "", "", "", string16()); net::GetSuggestedFilename(drop_data.url, "", "", "", "", "");
file_name = FilePathFromFilename(suggested_filename); file_name = FilePathFromFilename(suggested_filename);
} }

View File

@ -1,8 +1,8 @@
Index: message_loop.cc Index: message_loop.cc
=================================================================== ===================================================================
--- message_loop.cc (revision 105051) --- message_loop.cc (revision 106500)
+++ message_loop.cc (working copy) +++ message_loop.cc (working copy)
@@ -394,9 +394,13 @@ @@ -400,9 +400,13 @@
} }
void MessageLoop::AssertIdle() const { void MessageLoop::AssertIdle() const {
@ -19,9 +19,9 @@ Index: message_loop.cc
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Index: message_loop.h Index: message_loop.h
=================================================================== ===================================================================
--- message_loop.h (revision 105051) --- message_loop.h (revision 106500)
+++ message_loop.h (working copy) +++ message_loop.h (working copy)
@@ -363,6 +363,9 @@ @@ -367,6 +367,9 @@
// Asserts that the MessageLoop is "idle". // Asserts that the MessageLoop is "idle".
void AssertIdle() const; void AssertIdle() const;