0

recent: Store modifiedByMeDate in local Drive database.

In order to trigger refresh of local Drive metadata, DB version is
incremented from 14 to 15.

New timestamps will be used in Recent root.

Bug: 758677
Test: unit_tests
Change-Id: I51e85ce10d1777e1a0c0bb928c3da92faae376fb
Reviewed-on: https://chromium-review.googlesource.com/641735
Reviewed-by: Ryo Hashimoto <hashimoto@chromium.org>
Reviewed-by: Taiju Tsuiki <tzik@chromium.org>
Reviewed-by: Naoki Fukino <fukino@chromium.org>
Commit-Queue: Shuhei Takahashi <nya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#502215}
This commit is contained in:
Shuhei Takahashi
2017-09-15 09:22:17 +00:00
committed by Commit Bot
parent 05e0b72564
commit a25ace5694
27 changed files with 133 additions and 30 deletions

@ -298,10 +298,10 @@ TEST_F(ConflictResolverTest, ResolveConflict_Files) {
RunRemoteToLocalSyncerUntilIdle();
const std::string kTitle = "foo";
const std::string primary = CreateRemoteFile(app_root, kTitle, "data1");
CreateRemoteFile(app_root, kTitle, "data1");
CreateRemoteFile(app_root, kTitle, "data2");
CreateRemoteFile(app_root, kTitle, "data3");
CreateRemoteFile(app_root, kTitle, "data4");
const std::string primary = CreateRemoteFile(app_root, kTitle, "data4");
EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
RunRemoteToLocalSyncerUntilIdle();

@ -149,12 +149,17 @@ std::string FormatEntry(const base::FilePath& path,
const base::Time last_modified = base::Time::FromInternalValue(
file_info.last_modified());
const base::Time last_modified_by_me =
base::Time::FromInternalValue(entry.last_modified_by_me());
const base::Time last_accessed = base::Time::FromInternalValue(
file_info.last_accessed());
const base::Time creation_time = base::Time::FromInternalValue(
file_info.creation_time());
StringAppendF(&out, " last_modified: %s\n",
google_apis::util::FormatTimeAsString(last_modified).c_str());
StringAppendF(
&out, " last_modified_by_me: %s\n",
google_apis::util::FormatTimeAsString(last_modified_by_me).c_str());
StringAppendF(&out, " last_accessed: %s\n",
google_apis::util::FormatTimeAsString(last_accessed).c_str());
StringAppendF(&out, " creation_time: %s\n",

@ -921,8 +921,9 @@ void FileCache::CloseForWrite(const std::string& id) {
<< FileErrorToString(error);
return;
}
entry.mutable_file_info()->set_last_modified(
base::Time::Now().ToInternalValue());
int64_t now = base::Time::Now().ToInternalValue();
entry.mutable_file_info()->set_last_modified(now);
entry.set_last_modified_by_me(now);
error = storage_->PutEntry(entry);
if (error != FILE_ERROR_OK) {
LOG(ERROR) << "Failed to put entry: " << id << ", "

@ -558,6 +558,7 @@ TEST_F(FileCacheTest, OpenForWrite) {
ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
FileCache::FILE_OPERATION_COPY));
EXPECT_EQ(0, entry.file_info().last_modified());
EXPECT_EQ(0, entry.last_modified_by_me());
// Entry is not dirty nor opened.
EXPECT_FALSE(cache_->IsOpenedForWrite(id));
@ -587,9 +588,11 @@ TEST_F(FileCacheTest, OpenForWrite) {
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(cache_->IsOpenedForWrite(id));
// last_modified is updated.
// last_modified and last_modified_by_me are updated.
EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
EXPECT_NE(0, entry.file_info().last_modified());
EXPECT_NE(0, entry.last_modified_by_me());
EXPECT_EQ(entry.file_info().last_modified(), entry.last_modified_by_me());
// Close (2).
file_closer2.reset();

@ -125,15 +125,25 @@ FileError TryToCopyLocally(internal::ResourceMetadata* metadata,
// Copy locally.
ResourceEntry entry;
const int64_t now = base::Time::Now().ToInternalValue();
const int64_t last_modified =
params->preserve_last_modified
? params->src_entry.file_info().last_modified()
: now;
entry.set_title(params->dest_file_path.BaseName().AsUTF8Unsafe());
entry.set_parent_local_id(params->parent_entry.local_id());
entry.mutable_file_specific_info()->set_content_mime_type(
params->src_entry.file_specific_info().content_mime_type());
entry.set_metadata_edit_state(ResourceEntry::DIRTY);
entry.set_modification_date(base::Time::Now().ToInternalValue());
entry.mutable_file_info()->set_last_modified(
params->preserve_last_modified ?
params->src_entry.file_info().last_modified() : now);
entry.mutable_file_info()->set_last_modified(last_modified);
// preserve_last_modified=true preserves last_modified only.
// Regardless of preserve_last_modified's value, last_modified_by_me is
// always set to the same value as last_modified.
// This means that, even if preserve_last_modified=true, last_modified_by_me
// of the new file may differ from that of the original file.
// This behavior is due to the limitation in Drive API that we can not
// set different timestamps to last_modified and last_modified_by_me.
entry.set_last_modified_by_me(last_modified);
entry.mutable_file_info()->set_last_accessed(now);
std::string local_id;

@ -57,6 +57,8 @@ class CopyOperation {
// with a target of |dest_file_path|.
// If |preserve_last_modified| is set to true, this tries to preserve
// last modified time stamp. This is supported only on Drive API v2.
// Regardless of preserve_last_modified's value, last_modified_by_me timestamp
// will always be set to the same timestamp as last_modified.
// Invokes |callback| when finished with the result of the operation.
// |callback| must not be null.
void Copy(const base::FilePath& src_file_path,

@ -32,11 +32,12 @@ FileError CreateDirectoryRecursively(internal::ResourceMetadata* metadata,
title.AppendRelativePath(relative_file_path, &remaining_path);
ResourceEntry entry;
const base::Time now = base::Time::Now();
const int64_t now = base::Time::Now().ToInternalValue();
entry.set_title(title.AsUTF8Unsafe());
entry.mutable_file_info()->set_is_directory(true);
entry.mutable_file_info()->set_last_modified(now.ToInternalValue());
entry.mutable_file_info()->set_last_accessed(now.ToInternalValue());
entry.mutable_file_info()->set_last_modified(now);
entry.set_last_modified_by_me(now);
entry.mutable_file_info()->set_last_accessed(now);
entry.set_parent_local_id(parent_local_id);
entry.set_metadata_edit_state(ResourceEntry::DIRTY);
entry.set_modification_date(base::Time::Now().ToInternalValue());

@ -50,9 +50,10 @@ FileError UpdateLocalState(internal::ResourceMetadata* metadata,
mime_type = kMimeTypeOctetStream;
// Add the entry to the local resource metadata.
const base::Time now = base::Time::Now();
entry->mutable_file_info()->set_last_modified(now.ToInternalValue());
entry->mutable_file_info()->set_last_accessed(now.ToInternalValue());
const int64_t now = base::Time::Now().ToInternalValue();
entry->mutable_file_info()->set_last_modified(now);
entry->set_last_modified_by_me(now);
entry->mutable_file_info()->set_last_accessed(now);
entry->set_title(file_path.BaseName().AsUTF8Unsafe());
entry->set_parent_local_id(parent.local_id());
entry->set_metadata_edit_state(ResourceEntry::DIRTY);

@ -32,8 +32,10 @@ FileError UpdateLocalState(internal::ResourceMetadata* metadata,
PlatformFileInfoProto* file_info = entry->mutable_file_info();
if (!last_access_time.is_null())
file_info->set_last_accessed(last_access_time.ToInternalValue());
if (!last_modified_time.is_null())
if (!last_modified_time.is_null()) {
file_info->set_last_modified(last_modified_time.ToInternalValue());
entry->set_last_modified_by_me(last_modified_time.ToInternalValue());
}
entry->set_metadata_edit_state(ResourceEntry::DIRTY);
entry->set_modification_date(base::Time::Now().ToInternalValue());
return metadata->RefreshEntry(*entry);

@ -136,13 +136,24 @@ message ResourceEntry {
// Indicates whether this entry's metadata is edited locally or not.
optional EditState metadata_edit_state = 16;
// The time of the last modification.
// The time of the last modification. This is a timestamp used for conflict
// resolution and can not be modified arbitrarily by users, in contrast to
// PlatformFileInfoProto.last_modified and last_modified_by_me.
optional int64 modification_date = 18;
// List of new properties which are not synced yet via Drive API. Note, that
// currently existing properties are never fetched via Drive API, as they are
// never used. That would cause growing the proto size for no reason.
repeated Property new_properties = 19;
// The time of the last modification by the user. When the file is modified
// by other users, this timestamp is not updated.
// This timestamp is similar to last_modified in PlatformFileInfoProto rather
// than modification_date; it will be set to the same value as last_modified
// if the operation is done by the user. This field is here, not in
// PlatformFileInfoProto, just because this field does not have a
// corresponding field in base::File::Info.
optional int64 last_modified_by_me = 21;
}
// Container for the header part of ResourceMetadata.

@ -432,8 +432,13 @@ TEST_F(CopyOperationTest, PreserveLastModified) {
ResourceEntry entry2;
EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry));
EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &entry2));
EXPECT_NE(entry.file_info().last_modified(), entry.last_modified_by_me());
EXPECT_EQ(entry.file_info().last_modified(),
entry2.file_info().last_modified());
// Even with preserve_last_modified enabled, last_modified_by_me is forced to
// the same value as last_modified.
EXPECT_EQ(entry.file_info().last_modified(), entry2.last_modified_by_me());
}
TEST_F(CopyOperationTest, WaitForSyncComplete) {

@ -61,6 +61,8 @@ TEST_F(CreateDirectoryOperationTest, CreateDirectory) {
EXPECT_TRUE(entry.file_info().is_directory());
EXPECT_FALSE(base::Time::FromInternalValue(
entry.file_info().last_modified()).is_null());
EXPECT_FALSE(
base::Time::FromInternalValue(entry.last_modified_by_me()).is_null());
EXPECT_FALSE(base::Time::FromInternalValue(
entry.file_info().last_accessed()).is_null());
EXPECT_EQ(1U, delegate()->updated_local_ids().size());

@ -35,6 +35,8 @@ TEST_F(CreateFileOperationTest, CreateFile) {
EXPECT_EQ(ResourceEntry::DIRTY, entry.metadata_edit_state());
EXPECT_FALSE(base::Time::FromInternalValue(
entry.file_info().last_modified()).is_null());
EXPECT_FALSE(
base::Time::FromInternalValue(entry.last_modified_by_me()).is_null());
EXPECT_FALSE(base::Time::FromInternalValue(
entry.file_info().last_accessed()).is_null());

@ -49,6 +49,8 @@ TEST_F(TouchOperationTest, TouchFile) {
base::Time::FromInternalValue(entry.file_info().last_accessed()));
EXPECT_EQ(last_modified_time_utc,
base::Time::FromInternalValue(entry.file_info().last_modified()));
EXPECT_EQ(last_modified_time_utc,
base::Time::FromInternalValue(entry.last_modified_by_me()));
EXPECT_EQ(ResourceEntry::DIRTY, entry.metadata_edit_state());
EXPECT_EQ(1U, delegate()->get_changed_files().size());

@ -558,6 +558,7 @@ TEST_F(FileSystemTest, TouchFile) {
ASSERT_TRUE(server_entry);
EXPECT_EQ(last_accessed, server_entry->last_viewed_by_me_date());
EXPECT_EQ(last_modified, server_entry->modified_date());
EXPECT_EQ(last_modified, server_entry->modified_by_me_date());
}
TEST_F(FileSystemTest, TruncateFile) {

@ -83,6 +83,8 @@ bool ConvertFileResourceToResourceEntry(
PlatformFileInfoProto* file_info = converted.mutable_file_info();
file_info->set_last_modified(input.modified_date().ToInternalValue());
converted.set_last_modified_by_me(
input.modified_by_me_date().ToInternalValue());
// If the file has never been viewed (last_viewed_by_me_date().is_null() ==
// true), then we will set the last_accessed field in the protocol buffer to
// 0.

@ -41,6 +41,8 @@ TEST(ResourceEntryConversionTest, ConvertToResourceEntry_File) {
file_resource.set_created_date(GetTestTime());
file_resource.set_modified_date(
GetTestTime() + base::TimeDelta::FromSeconds(10));
file_resource.set_modified_by_me_date(GetTestTime() +
base::TimeDelta::FromSeconds(5));
file_resource.set_mime_type("audio/mpeg");
file_resource.set_alternate_link(GURL("https://file_link_alternate"));
file_resource.set_file_size(892721);
@ -63,6 +65,8 @@ TEST(ResourceEntryConversionTest, ConvertToResourceEntry_File) {
EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
entry.file_info().last_modified());
EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
entry.last_modified_by_me());
// Last accessed value equal to 0 means that the file has never been viewed.
EXPECT_EQ(0, entry.file_info().last_accessed());
EXPECT_EQ(file_resource.created_date().ToInternalValue(),
@ -88,6 +92,8 @@ TEST(ResourceEntryConversionTest,
file_resource.set_created_date(GetTestTime());
file_resource.set_modified_date(
GetTestTime() + base::TimeDelta::FromSeconds(10));
file_resource.set_modified_by_me_date(GetTestTime() +
base::TimeDelta::FromSeconds(5));
file_resource.set_last_viewed_by_me_date(
GetTestTime() + base::TimeDelta::FromSeconds(20));
file_resource.set_mime_type(util::kGoogleDocumentMimeType);
@ -113,6 +119,8 @@ TEST(ResourceEntryConversionTest,
EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
entry.file_info().last_modified());
EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
entry.last_modified_by_me());
EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
entry.file_info().last_accessed());
EXPECT_EQ(file_resource.created_date().ToInternalValue(),
@ -137,6 +145,8 @@ TEST(ResourceEntryConversionTest,
file_resource.set_created_date(GetTestTime());
file_resource.set_modified_date(
GetTestTime() + base::TimeDelta::FromSeconds(10));
file_resource.set_modified_by_me_date(GetTestTime() +
base::TimeDelta::FromSeconds(5));
file_resource.set_last_viewed_by_me_date(
GetTestTime() + base::TimeDelta::FromSeconds(20));
file_resource.set_mime_type(util::kDriveFolderMimeType);
@ -164,6 +174,8 @@ TEST(ResourceEntryConversionTest,
EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
entry.file_info().last_modified());
EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
entry.last_modified_by_me());
EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
entry.file_info().last_accessed());
EXPECT_EQ(file_resource.created_date().ToInternalValue(),
@ -180,6 +192,8 @@ TEST(ResourceEntryConversionTest,
file_resource.set_created_date(GetTestTime());
file_resource.set_modified_date(
GetTestTime() + base::TimeDelta::FromSeconds(10));
file_resource.set_modified_by_me_date(GetTestTime() +
base::TimeDelta::FromSeconds(5));
file_resource.set_last_viewed_by_me_date(
GetTestTime() + base::TimeDelta::FromSeconds(20));
file_resource.set_mime_type(util::kGoogleDocumentMimeType);
@ -203,6 +217,8 @@ TEST(ResourceEntryConversionTest,
EXPECT_EQ(file_resource.modified_date().ToInternalValue(),
entry.file_info().last_modified());
EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(),
entry.last_modified_by_me());
EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(),
entry.file_info().last_accessed());
EXPECT_EQ(file_resource.created_date().ToInternalValue(),

@ -249,7 +249,7 @@ bool ResourceMetadataStorage::UpgradeOldDB(
const base::FilePath& directory_path) {
base::ThreadRestrictions::AssertIOAllowed();
static_assert(
kDBVersion == 14,
kDBVersion == 15,
"database version and this function must be updated at the same time");
const base::FilePath resource_map_path =
@ -521,6 +521,16 @@ bool ResourceMetadataStorage::UpgradeOldDB(
return false;
batch.Put(GetHeaderDBKey(), serialized_header);
return resource_map->Write(leveldb::WriteOptions(), &batch).ok();
} else if (header.version() < 15) {
// Just need to clear largest_changestamp.
// Put header with the latest version number.
std::string serialized_header;
if (!GetDefaultHeaderEntry().SerializeToString(&serialized_header))
return false;
leveldb::WriteBatch batch;
batch.Put(GetHeaderDBKey(), serialized_header);
return resource_map->Write(leveldb::WriteOptions(), &batch).ok();
}

@ -39,7 +39,7 @@ class ResourceMetadataStorage {
public:
// This should be incremented when incompatibility change is made to DB
// format.
static const int kDBVersion = 14;
static const int kDBVersion = 15;
// Object to iterate over entries stored in this storage.
class Iterator {

@ -111,7 +111,7 @@ const char kFileResourceFields[] =
"imageMediaMetadata/width,"
"imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
"parents(id,parentLink),alternateLink,"
"modifiedDate,lastViewedByMeDate,shared";
"modifiedDate,lastViewedByMeDate,shared,modifiedByMeDate";
const char kFileResourceOpenWithLinksFields[] =
"kind,id,openWithLinks/*";
const char kFileResourceShareLinkFields[] =
@ -122,15 +122,15 @@ const char kFileListFields[] =
"imageMediaMetadata/width,"
"imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
"parents(id,parentLink),alternateLink,"
"modifiedDate,lastViewedByMeDate,shared),nextLink";
"modifiedDate,lastViewedByMeDate,shared,modifiedByMeDate),nextLink";
const char kChangeListFields[] =
"kind,items(type,file(kind,id,title,createdDate,sharedWithMeDate,"
"mimeType,md5Checksum,fileSize,labels/trashed,labels/starred,"
"imageMediaMetadata/width,"
"imageMediaMetadata/height,imageMediaMetadata/rotation,etag,"
"parents(id,parentLink),alternateLink,modifiedDate,"
"lastViewedByMeDate,shared),teamDrive(kind,id,name,capabilities),"
"teamDriveId,"
"lastViewedByMeDate,shared,modifiedByMeDate),"
"teamDrive(kind,id,name,capabilities),teamDriveId,"
"deleted,id,fileId,modificationDate),nextLink,"
"largestChangeId";
const char kTeamDrivesListFields[] =

@ -237,7 +237,7 @@ struct FakeDriveService::UploadSession {
FakeDriveService::FakeDriveService()
: about_resource_(new AboutResource),
published_date_seq_(0),
date_seq_(0),
next_upload_sequence_number_(0),
default_max_results_(0),
resource_id_count_(0),
@ -929,8 +929,10 @@ CancelCallback FakeDriveService::CopyResource(
parents.push_back(parent);
*new_file->mutable_parents() = parents;
if (!last_modified.is_null())
if (!last_modified.is_null()) {
new_file->set_modified_date(last_modified);
new_file->set_modified_by_me_date(last_modified);
}
AddNewChangestamp(new_change);
UpdateETag(new_file);
@ -998,8 +1000,10 @@ CancelCallback FakeDriveService::UpdateResource(
*file->mutable_parents() = parents;
}
if (!last_modified.is_null())
if (!last_modified.is_null()) {
file->set_modified_date(last_modified);
file->set_modified_by_me_date(last_modified);
}
if (!last_viewed_by_me.is_null())
file->set_last_viewed_by_me_date(last_viewed_by_me);
@ -1564,6 +1568,7 @@ void FakeDriveService::SetLastModifiedTime(
ChangeResource* change = &entry->change_resource;
FileResource* file = change->mutable_file();
file->set_modified_date(last_modified_time);
file->set_modified_by_me_date(last_modified_time);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@ -1716,9 +1721,12 @@ const FakeDriveService::EntryInfo* FakeDriveService::AddNewEntry(
AddNewChangestamp(new_change);
UpdateETag(new_file);
base::Time published_date =
base::Time() + base::TimeDelta::FromMilliseconds(++published_date_seq_);
new_file->set_created_date(published_date);
new_file->set_created_date(base::Time() +
base::TimeDelta::FromMilliseconds(++date_seq_));
new_file->set_modified_by_me_date(
base::Time() + base::TimeDelta::FromMilliseconds(++date_seq_));
new_file->set_modified_date(base::Time() +
base::TimeDelta::FromMilliseconds(++date_seq_));
EntryInfo* raw_new_entry = new_entry.get();
entries_[resource_id] = std::move(new_entry);

@ -406,7 +406,7 @@ class FakeDriveService : public DriveServiceInterface {
team_drive_value_;
std::map<GURL, UploadSession> upload_sessions_;
int64_t published_date_seq_;
int64_t date_seq_;
int64_t next_upload_sequence_number_;
int default_max_results_;
int resource_id_count_;

@ -1125,6 +1125,7 @@ TEST_F(FakeDriveServiceTest, CopyResource) {
EXPECT_NE(kResourceId, entry->file_id());
EXPECT_EQ("new title", entry->title());
EXPECT_EQ(modified_date_utc, entry->modified_date());
EXPECT_EQ(modified_date_utc, entry->modified_by_me_date());
EXPECT_TRUE(HasParent(entry->file_id(), kParentResourceId));
// Should be incremented as a new hosted document was created.
EXPECT_EQ(old_largest_change_id + 1,
@ -1225,6 +1226,7 @@ TEST_F(FakeDriveServiceTest, UpdateResource) {
EXPECT_EQ(kResourceId, entry->file_id());
EXPECT_EQ("new title", entry->title());
EXPECT_EQ(modified_date_utc, entry->modified_date());
EXPECT_EQ(modified_date_utc, entry->modified_by_me_date());
EXPECT_EQ(viewed_date_utc, entry->last_viewed_by_me_date());
EXPECT_TRUE(HasParent(kResourceId, kParentResourceId));
// Should be incremented as a new hosted document was created.
@ -2180,6 +2182,7 @@ TEST_F(FakeDriveServiceTest, SetLastModifiedTime_ExistingFile) {
EXPECT_EQ(HTTP_SUCCESS, error);
ASSERT_TRUE(entry);
EXPECT_EQ(time, entry->modified_date());
EXPECT_EQ(time, entry->modified_by_me_date());
}
TEST_F(FakeDriveServiceTest, SetLastModifiedTime_NonexistingFile) {

@ -150,6 +150,7 @@ const char kMimeType[] = "mimeType";
const char kCreatedDate[] = "createdDate";
const char kModificationDate[] = "modificationDate";
const char kModifiedDate[] = "modifiedDate";
const char kModifiedByMeDate[] = "modifiedByMeDate";
const char kLastViewedByMeDate[] = "lastViewedByMeDate";
const char kSharedWithMeDate[] = "sharedWithMeDate";
const char kMd5Checksum[] = "md5Checksum";
@ -623,6 +624,9 @@ void FileResource::RegisterJSONConverter(
kModifiedDate,
&FileResource::modified_date_,
&util::GetTimeFromString);
converter->RegisterCustomField<base::Time>(
kModifiedByMeDate, &FileResource::modified_by_me_date_,
&util::GetTimeFromString);
converter->RegisterCustomField<base::Time>(
kLastViewedByMeDate,
&FileResource::last_viewed_by_me_date_,

@ -639,6 +639,9 @@ class FileResource {
// Returns modified time of this file.
const base::Time& modified_date() const { return modified_date_; }
// Returns last modified time by the user.
const base::Time& modified_by_me_date() const { return modified_by_me_date_; }
// Returns last access time by the user.
const base::Time& last_viewed_by_me_date() const {
return last_viewed_by_me_date_;
@ -697,6 +700,9 @@ class FileResource {
void set_modified_date(const base::Time& modified_date) {
modified_date_ = modified_date;
}
void set_modified_by_me_date(const base::Time& modified_by_me_date) {
modified_by_me_date_ = modified_by_me_date;
}
void set_last_viewed_by_me_date(const base::Time& last_viewed_by_me_date) {
last_viewed_by_me_date_ = last_viewed_by_me_date;
}
@ -738,6 +744,7 @@ class FileResource {
ImageMediaMetadata image_media_metadata_;
base::Time created_date_;
base::Time modified_date_;
base::Time modified_by_me_date_;
base::Time last_viewed_by_me_date_;
base::Time shared_with_me_date_;
bool shared_;

@ -192,6 +192,11 @@ TEST(DriveAPIParserTest, FileListParser) {
util::GetTimeFromString("2012-07-27T05:43:20.269Z", &modified_time));
EXPECT_EQ(modified_time, file1.modified_date());
base::Time modified_by_me_time;
ASSERT_TRUE(util::GetTimeFromString("2012-07-27T05:30:20.269Z",
&modified_by_me_time));
EXPECT_EQ(modified_by_me_time, file1.modified_by_me_date());
ASSERT_EQ(1U, file1.parents().size());
EXPECT_EQ("0B4v7G8yEYAWHYW1OcExsUVZLABC", file1.parents()[0].file_id());

@ -31,7 +31,7 @@
},
"createdDate": "2012-07-24T08:51:16.570Z",
"modifiedDate": "2012-07-27T05:43:20.269Z",
"modifiedByMeDate": "2012-07-27T05:43:20.269Z",
"modifiedByMeDate": "2012-07-27T05:30:20.269Z",
"lastViewedByMeDate": "2012-07-27T05:43:20.269Z",
"parents": [
{