Commit aadba2a8 authored by kochi@chromium.org's avatar kochi@chromium.org

Pass parsed ChangeList to GDataFileSystem.

Get ChangeList using Drive V2 API and then converts to
DocumentFeed.  This is not optimal but change can be minimal
to make file list appear in FileBrowser UI, which makes
other development/debugging/refactoring easier.

This depends on the change in
https://chromiumcodereview.appspot.com/10837201/
for GetKind() function.

BUG=chromium:127728
TEST=specify "--enable-drive-v2-api" and open file browser (Ctrl-M), then go to drive folder and see if file listing works.

Review URL: https://chromiumcodereview.appspot.com/10837201

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151445 0039d316-1c4b-4281-b951-d872f2087c98
parent 98846aa3
......@@ -464,6 +464,29 @@ void GDataWapiFeedLoader::LoadFromServer(
scoped_ptr<std::vector<DocumentFeed*> > feed_list(
new std::vector<DocumentFeed*>);
const base::TimeTicks start_time = base::TimeTicks::Now();
if (gdata::util::IsDriveV2ApiEnabled()) {
documents_service_->GetChangelist(
feed_to_load,
start_changestamp,
base::Bind(&GDataWapiFeedLoader::OnGetChangelist,
weak_ptr_factory_.GetWeakPtr(),
initial_origin,
feed_load_callback,
base::Owned(new GetDocumentsParams(
start_changestamp,
root_feed_changestamp,
feed_list.release(),
should_fetch_multiple_feeds,
search_file_path,
search_query,
directory_resource_id,
entry_found_callback,
NULL)),
start_time));
return;
}
documents_service_->GetDocuments(
feed_to_load,
start_changestamp,
......@@ -554,7 +577,6 @@ void GDataWapiFeedLoader::OnGetDocuments(
if (!callback.is_null()) {
callback.Run(params, GDATA_FILE_ERROR_FAILED);
}
return;
}
const bool has_next_feed_url = current_feed->GetNextFeedURL(&next_feed_url);
......@@ -640,6 +662,126 @@ void GDataWapiFeedLoader::OnGetDocuments(
callback.Run(params, error);
}
void GDataWapiFeedLoader::OnGetChangelist(
ContentOrigin initial_origin,
const LoadDocumentFeedCallback& callback,
GetDocumentsParams* params,
base::TimeTicks start_time,
GDataErrorCode status,
scoped_ptr<base::Value> data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (params->feed_list->empty()) {
UMA_HISTOGRAM_TIMES("Drive.InitialFeedLoadTime",
base::TimeTicks::Now() - start_time);
}
GDataFileError error = util::GDataToGDataFileError(status);
if (error == GDATA_FILE_OK &&
(!data.get() || data->GetType() != Value::TYPE_DICTIONARY)) {
error = GDATA_FILE_ERROR_FAILED;
}
if (error != GDATA_FILE_OK) {
directory_service_->set_origin(initial_origin);
if (!callback.is_null())
callback.Run(params, error);
return;
}
GURL next_feed_url;
scoped_ptr<ChangeList> current_feed(ChangeList::CreateFrom(*data));
if (!current_feed.get()) {
if (!callback.is_null()) {
callback.Run(params, GDATA_FILE_ERROR_FAILED);
}
return;
}
const bool has_next_feed = !current_feed->next_page_token().empty();
#ifndef NDEBUG
// Save initial root feed for analysis.
std::string file_name =
base::StringPrintf("DEBUG_changelist_%" PRId64 ".json",
params->start_changestamp);
util::PostBlockingPoolSequencedTask(
FROM_HERE,
blocking_task_runner_,
base::Bind(&SaveFeedOnBlockingPoolForDebugging,
cache_->GetCacheDirectoryPath(
GDataCache::CACHE_TYPE_META).Append(file_name),
base::Passed(&data)));
#endif
// Add the current feed to the list of collected feeds for this directory.
scoped_ptr<DocumentFeed> feed =
DocumentFeed::CreateFromChangeList(*current_feed);
params->feed_list->push_back(feed.release());
// Compute and notify the number of entries fetched so far.
int num_accumulated_entries = 0;
for (size_t i = 0; i < params->feed_list->size(); ++i)
num_accumulated_entries += params->feed_list->at(i)->entries().size();
// Check if we need to collect more data to complete the directory list.
if (params->should_fetch_multiple_feeds && has_next_feed) {
// Post an UI update event to make the UI smoother.
GetDocumentsUiState* ui_state = params->ui_state.get();
if (ui_state == NULL) {
ui_state = new GetDocumentsUiState(base::TimeTicks::Now());
params->ui_state.reset(ui_state);
}
DCHECK(ui_state);
if ((ui_state->num_fetched_documents - ui_state->num_showing_documents)
< kFetchUiUpdateStep) {
// Currently the UI update is stopped. Start UI periodic callback.
MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&GDataWapiFeedLoader::OnNotifyDocumentFeedFetched,
weak_ptr_factory_.GetWeakPtr(),
ui_state->weak_ptr_factory.GetWeakPtr()));
}
ui_state->num_fetched_documents = num_accumulated_entries;
ui_state->feed_fetching_elapsed_time = base::TimeTicks::Now() - start_time;
// Kick of the remaining part of the feeds.
documents_service_->GetChangelist(
current_feed->next_link(),
params->start_changestamp,
base::Bind(&GDataWapiFeedLoader::OnGetChangelist,
weak_ptr_factory_.GetWeakPtr(),
initial_origin,
callback,
base::Owned(
new GetDocumentsParams(
params->start_changestamp,
params->root_feed_changestamp,
params->feed_list.release(),
params->should_fetch_multiple_feeds,
params->search_file_path,
params->search_query,
params->directory_resource_id,
params->callback,
NULL)),
start_time));
return;
}
// Notify the observers that a document feed is fetched.
FOR_EACH_OBSERVER(Observer, observers_,
OnDocumentFeedFetched(num_accumulated_entries));
UMA_HISTOGRAM_TIMES("Drive.EntireFeedLoadTime",
base::TimeTicks::Now() - start_time);
if (!callback.is_null())
callback.Run(params, error);
}
void GDataWapiFeedLoader::OnNotifyDocumentFeedFetched(
base::WeakPtr<GetDocumentsUiState> ui_state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......
......@@ -211,6 +211,15 @@ class GDataWapiFeedLoader {
GDataErrorCode status,
scoped_ptr<base::Value> data);
// Callback for handling response from |GDataDocumentsService::GetChanglist|.
// Invokes |callback| when done.
void OnGetChangelist(ContentOrigin initial_origin,
const LoadDocumentFeedCallback& callback,
GetDocumentsParams* params,
base::TimeTicks start_time,
GDataErrorCode status,
scoped_ptr<base::Value> data);
// Save filesystem to disk.
void SaveFileSystem();
......
......@@ -15,6 +15,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chromeos/gdata/drive_api_parser.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h"
#include "third_party/libxml/chromium/libxml_utils.h"
......@@ -803,6 +804,83 @@ DocumentEntry* DocumentEntry::CreateFromXml(XmlReader* xml_reader) {
return entry;
}
// static
DocumentEntry* DocumentEntry::CreateFromFileResource(const FileResource& file) {
scoped_ptr<DocumentEntry> entry(new DocumentEntry());
// DocumentEntry
entry->resource_id_ = file.file_id();
entry->id_ = file.file_id();
entry->kind_ = file.GetKind();
entry->title_ = UTF8ToUTF16(file.title());
entry->published_time_ = file.created_date();
// TODO(kochi): entry->labels_
entry->content_.url_ = file.web_content_link();
entry->content_.mime_type_ = file.mime_type();
// TODO(kochi): entry->feed_links_
// For file entries
entry->filename_ = UTF8ToUTF16(file.title());
entry->suggested_filename_ = UTF8ToUTF16(file.title());
entry->file_md5_ = file.md5_checksum();
entry->file_size_ = file.file_size();
entry->deleted_ = false; // later filled by CreateFromChangeResource.
entry->removed_ = false; // later filled by CreateFromChangeResource.
// FeedEntry
entry->etag_ = file.etag();
// entry->authors_
// entry->links_.
if (!file.parents().empty()) {
Link* link = new Link();
link->type_ = Link::PARENT;
link->href_ = file.parents()[0]->parent_link();
entry->links_.push_back(link);
}
if (!file.self_link().is_empty()) {
Link* link = new Link();
link->type_ = Link::EDIT;
link->href_ = file.self_link();
entry->links_.push_back(link);
}
if (!file.thumbnail_link().is_empty()) {
Link* link = new Link();
link->type_ = Link::THUMBNAIL;
link->href_ = file.thumbnail_link();
entry->links_.push_back(link);
}
if (!file.alternate_link().is_empty()) {
Link* link = new Link();
link->type_ = Link::ALTERNATE;
link->href_ = file.alternate_link();
entry->links_.push_back(link);
}
if (!file.embed_link().is_empty()) {
Link* link = new Link();
link->type_ = Link::EMBED;
link->href_ = file.embed_link();
entry->links_.push_back(link);
}
// entry->categories_
entry->updated_time_ = file.modified_by_me_date();
// TODO: Do we need this?
entry->FillRemainingFields();
return entry.release();
}
// static
DocumentEntry*
DocumentEntry::CreateFromChangeResource(const ChangeResource& change) {
DocumentEntry* entry = CreateFromFileResource(change.file());
entry->deleted_ = change.is_deleted();
entry->removed_ = change.is_deleted();
return entry;
}
// static
std::string DocumentEntry::GetEntryNodeName() {
return kEntryNode;
......@@ -878,6 +956,23 @@ scoped_ptr<DocumentFeed> DocumentFeed::CreateFrom(const base::Value& value) {
return feed.Pass();
}
// static
scoped_ptr<DocumentFeed> DocumentFeed::CreateFromChangeList(
const ChangeList& changelist) {
scoped_ptr<DocumentFeed> feed(new DocumentFeed());
int64 largest_changestamp = 0;
ScopedVector<ChangeResource>::const_iterator iter =
changelist.items().begin();
while (iter != changelist.items().end()) {
const FileResource& file = (*iter)->file();
largest_changestamp = std::max(largest_changestamp, (*iter)->change_id());
feed->entries_.push_back(DocumentEntry::CreateFromFileResource(file));
++iter;
}
feed->largest_changestamp_ = largest_changestamp;
return feed.Pass();
}
bool DocumentFeed::GetNextFeedURL(GURL* url) {
DCHECK(url);
for (size_t i = 0; i < links_.size(); ++i) {
......
......@@ -36,6 +36,13 @@ class RepeatedMessageConverter;
// http://code.google.com/apis/documents/.
namespace gdata {
// TODO(kochi): These forward declarations will be unnecessary once
// http://crbug.com/142293 is resolved.
class ChangeList;
class ChangeResource;
class FileList;
class FileResource;
// Defines link (URL) of an entity (document, file, feed...). Each entity could
// have more than one link representing it.
class Link {
......@@ -371,6 +378,14 @@ class DocumentEntry : public FeedEntry {
// Creates document entry from parsed XML.
static DocumentEntry* CreateFromXml(XmlReader* xml_reader);
// Creates document entry from FileResource.
// TODO(kochi): This should go away soon. http://crbug.com/142293
static DocumentEntry* CreateFromFileResource(const FileResource& file);
// Creates document entry from ChangeResource.
// Todo(Kochi): This should go away soon. http://crbug.com/142293
static DocumentEntry* CreateFromChangeResource(const ChangeResource& change);
// Returns name of entry node.
static std::string GetEntryNodeName();
......@@ -512,6 +527,10 @@ class DocumentFeed : public FeedEntry {
// FillRemainingFields comment and implementation in DocumentEntry
// class for the details.
static scoped_ptr<DocumentFeed> CreateFrom(const base::Value& value);
// Variant of CreateFrom() above, creates feed from parsed ChangeList.
// TODO(kochi): This should go away soon. http://crbug.com/142293
static scoped_ptr<DocumentFeed> CreateFromChangeList(
const ChangeList& changelist);
// Registers the mapping between JSON field names and the members in
// this class.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment