Remove |double| timestamp code from blink::File
This CL changes:
- all timestamp arguments of File,
- the return value of LastModifiedMS(), and
- the type of snapshot_modification_time_ms_
from double to base::Optional<base::Time>.
This renames
- LastModifiedMS() to LastModifiedTime() and
- snapshot_modification_time_ms_ to snapshot_modification_time_
and removes
- File::LastModifiedDate(),
- InvalidFileTime() in file_metadata.h,
- IsValidFileTime() in file_metadata.h,
- ToJsTimeOrNaN() in file_metadata.h, and
- JsTimeToOptionalTime() in file_metadata.h.
This CL fixes File.lastModified behavior for timestamps later than
275760-09-13T00:00Z by removing unnecessary double-base:Time
conversions.
* v8_script_value_serializer_test.cc
Do not wrap test cases with |namespace { ... }| because
FRIEND_TEST_ALL_PREFIXES() doesn't work with it.
Change-Id: I630d869641ea033b68534f17178e78b8fc2d1953
Bug: 988343
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1942671
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: Joshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720806}
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
index 4034540..d9688ad0 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -151,8 +152,8 @@
TEST(SerializedScriptValueTest, FileConstructorFile) {
V8TestingScope scope;
scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create();
- auto* original_file =
- MakeGarbageCollected<File>("hello.txt", 12345678.0, blob_data_handle);
+ auto* original_file = MakeGarbageCollected<File>(
+ "hello.txt", base::Time::FromJsTime(12345678.0), blob_data_handle);
ASSERT_FALSE(original_file->HasBackingFile());
ASSERT_EQ(File::kIsNotUserVisible, original_file->GetUserVisibility());
ASSERT_EQ("hello.txt", original_file->name());
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index 1c5ebe0..d08e5e12 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h"
#include "base/numerics/checked_math.h"
+#include "base/optional.h"
+#include "base/time/time.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
@@ -628,9 +630,12 @@
auto blob_handle = GetOrCreateBlobDataHandle(uuid, type, kSizeForDataHandle);
if (!blob_handle)
return nullptr;
- return File::CreateFromSerialization(
- path, name, relative_path, user_visibility, has_snapshot, size,
- last_modified_ms, std::move(blob_handle));
+ base::Optional<base::Time> last_modified;
+ if (has_snapshot && std::isfinite(last_modified_ms))
+ last_modified = base::Time::FromJsTime(last_modified_ms);
+ return File::CreateFromSerialization(path, name, relative_path,
+ user_visibility, has_snapshot, size,
+ last_modified, std::move(blob_handle));
}
File* V8ScriptValueDeserializer::ReadFileIndex() {
@@ -647,9 +652,9 @@
}
if (!blob_handle)
return nullptr;
- return File::CreateFromIndexedSerialization(
- info.FilePath(), info.FileName(), info.size(),
- ToJsTimeOrNaN(info.LastModified()), blob_handle);
+ return File::CreateFromIndexedSerialization(info.FilePath(), info.FileName(),
+ info.size(), info.LastModified(),
+ blob_handle);
}
DOMRectReadOnly* V8ScriptValueDeserializer::ReadDOMRectReadOnly() {
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index 39433ca4..7308bc6 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -145,8 +146,6 @@
return testing::AssertionSuccess();
}
-namespace {
-
TEST(V8ScriptValueSerializerTest, RoundTripJSONLikeValue) {
// Ensure that simple JavaScript objects work.
// There are more exhaustive tests of JavaScript objects in V8.
@@ -1450,7 +1449,7 @@
TEST(V8ScriptValueSerializerTest, RoundTripFileBackedByBlob) {
V8TestingScope scope;
- const double kModificationTime = 0.0;
+ const base::Time kModificationTime = base::Time::UnixEpoch();
scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create();
auto* file = MakeGarbageCollected<File>("/native/path", kModificationTime,
blob_data_handle);
@@ -1494,17 +1493,22 @@
}
// Used for checking that times provided are between now and the current time
-// when the checker was constructed, according to WTF::currentTime.
+// when the checker was constructed, according to base::Time::Now.
class TimeIntervalChecker {
public:
- TimeIntervalChecker() : start_time_(base::Time::Now()) {}
- bool WasAliveAt(double time_in_milliseconds) {
- base::Time time = base::Time::FromJsTime(time_in_milliseconds);
- return start_time_ <= time && time <= base::Time::Now();
+ TimeIntervalChecker() : start_time_(NowInMilliseconds()) {}
+
+ bool WasAliveAt(int64_t time_in_milliseconds) {
+ return start_time_ <= time_in_milliseconds &&
+ time_in_milliseconds <= NowInMilliseconds();
}
private:
- const base::Time start_time_;
+ static int64_t NowInMilliseconds() {
+ return (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds();
+ }
+
+ const int64_t start_time_;
};
TEST(V8ScriptValueSerializerTest, DecodeFileV3) {
@@ -1525,7 +1529,7 @@
EXPECT_EQ("text/plain", new_file->type());
EXPECT_FALSE(new_file->HasValidSnapshotMetadata());
EXPECT_EQ(0u, new_file->size());
- EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->LastModifiedDate()));
+ EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->lastModified()));
EXPECT_EQ(File::kIsUserVisible, new_file->GetUserVisibility());
}
@@ -1550,7 +1554,7 @@
EXPECT_EQ("text/plain", new_file->type());
EXPECT_FALSE(new_file->HasValidSnapshotMetadata());
EXPECT_EQ(0u, new_file->size());
- EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->LastModifiedDate()));
+ EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->lastModified()));
EXPECT_EQ(File::kIsUserVisible, new_file->GetUserVisibility());
}
@@ -1577,7 +1581,9 @@
EXPECT_EQ(512u, new_file->size());
// From v4 to v7, the last modified time is written in seconds.
// So -0.25 represents 250 ms before the Unix epoch.
- EXPECT_EQ(-250.0, new_file->LastModifiedDate());
+ EXPECT_EQ(-250, new_file->lastModified());
+ EXPECT_EQ(base::TimeDelta::FromMillisecondsD(-250.0),
+ new_file->LastModifiedTime() - base::Time::UnixEpoch());
}
TEST(V8ScriptValueSerializerTest, DecodeFileV7) {
@@ -1601,7 +1607,7 @@
EXPECT_EQ("text/plain", new_file->type());
EXPECT_FALSE(new_file->HasValidSnapshotMetadata());
EXPECT_EQ(0u, new_file->size());
- EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->LastModifiedDate()));
+ EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->lastModified()));
EXPECT_EQ(File::kIsNotUserVisible, new_file->GetUserVisibility());
}
@@ -1628,7 +1634,10 @@
EXPECT_EQ(512u, new_file->size());
// From v8, the last modified time is written in milliseconds.
// So -0.25 represents 0.25 ms before the Unix epoch.
- EXPECT_EQ(-0.25, new_file->LastModifiedDate());
+ EXPECT_EQ(base::TimeDelta::FromMillisecondsD(-0.25),
+ new_file->LastModifiedTime() - base::Time::UnixEpoch());
+ // lastModified IDL attribute can't represent -0.25 ms.
+ EXPECT_EQ(INT64_C(0), new_file->lastModified());
EXPECT_EQ(File::kIsUserVisible, new_file->GetUserVisibility());
}
@@ -1758,7 +1767,7 @@
EXPECT_EQ("text/plain", new_file->type());
EXPECT_FALSE(new_file->HasValidSnapshotMetadata());
EXPECT_EQ(0u, new_file->size());
- EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->LastModifiedDate()));
+ EXPECT_TRUE(time_interval_checker.WasAliveAt(new_file->lastModified()));
EXPECT_EQ(File::kIsNotUserVisible, new_file->GetUserVisibility());
}
@@ -1889,5 +1898,4 @@
EXPECT_FALSE(transferred->locked(script_state, ASSERT_NO_EXCEPTION));
}
-} // namespace
} // namespace blink
diff --git a/third_party/blink/renderer/core/clipboard/data_object_item.cc b/third_party/blink/renderer/core/clipboard/data_object_item.cc
index 4392c2a..5016284 100644
--- a/third_party/blink/renderer/core/clipboard/data_object_item.cc
+++ b/third_party/blink/renderer/core/clipboard/data_object_item.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/clipboard/data_object_item.h"
+#include "base/time/time.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
@@ -156,8 +157,8 @@
data->AppendBytes(png_data.data(), png_data.size());
const uint64_t length = data->length();
auto blob = BlobDataHandle::Create(std::move(data), length);
- return MakeGarbageCollected<File>(
- "image.png", base::Time::Now().ToDoubleT() * 1000.0, std::move(blob));
+ return MakeGarbageCollected<File>("image.png", base::Time::Now(),
+ std::move(blob));
}
return nullptr;
diff --git a/third_party/blink/renderer/core/exported/web_drag_data_test.cc b/third_party/blink/renderer/core/exported/web_drag_data_test.cc
index bbf6a69..41e2150 100644
--- a/third_party/blink/renderer/core/exported/web_drag_data_test.cc
+++ b/third_party/blink/renderer/core/exported/web_drag_data_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/public/platform/web_drag_data.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
@@ -17,8 +18,9 @@
// Native file.
data_object->Add(MakeGarbageCollected<File>("/native/path"));
- data_object->Add(
- MakeGarbageCollected<File>("name", 0.0, BlobDataHandle::Create()));
+ // Blob file.
+ data_object->Add(MakeGarbageCollected<File>("name", base::Time::UnixEpoch(),
+ BlobDataHandle::Create()));
// User visible snapshot file.
{
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
index f1806d0d..04b0599 100644
--- a/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_data_loader.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/optional.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "third_party/blink/renderer/core/fetch/multipart_parser.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
@@ -422,7 +423,7 @@
DCHECK(!string_builder_);
const auto size = blob_data_->length();
auto* file = MakeGarbageCollected<File>(
- filename_, InvalidFileTime(),
+ filename_, base::nullopt,
BlobDataHandle::Create(std::move(blob_data_), size));
form_data->append(name_, file, filename_);
return true;
diff --git a/third_party/blink/renderer/core/fileapi/file.cc b/third_party/blink/renderer/core/fileapi/file.cc
index a925d34e..b94b64e 100644
--- a/third_party/blink/renderer/core/fileapi/file.cc
+++ b/third_party/blink/renderer/core/fileapi/file.cc
@@ -132,11 +132,16 @@
const FilePropertyBag* options) {
DCHECK(options->hasType());
- double last_modified;
- if (options->hasLastModified())
- last_modified = static_cast<double>(options->lastModified());
- else
- last_modified = base::Time::Now().ToDoubleT() * 1000.0;
+ base::Time last_modified;
+ if (options->hasLastModified()) {
+ // We don't use base::Time::FromJsTime(double) here because
+ // options->lastModified() is a 64-bit integer, and casting it to
+ // double is lossy.
+ last_modified = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(options->lastModified());
+ } else {
+ last_modified = base::Time::Now();
+ }
DCHECK(options->hasEndings());
bool normalize_line_endings_to_native = options->endings() == "native";
if (normalize_line_endings_to_native)
@@ -194,8 +199,7 @@
has_backing_file_(true),
user_visibility_(user_visibility),
path_(path),
- name_(FilePathToWebString(WebStringToFilePath(path).BaseName())),
- snapshot_modification_time_ms_(InvalidFileTime()) {}
+ name_(FilePathToWebString(WebStringToFilePath(path).BaseName())) {}
File::File(const String& path,
const String& name,
@@ -207,8 +211,7 @@
has_backing_file_(true),
user_visibility_(user_visibility),
path_(path),
- name_(name),
- snapshot_modification_time_ms_(InvalidFileTime()) {}
+ name_(name) {}
File::File(const String& path,
const String& name,
@@ -216,29 +219,28 @@
UserVisibility user_visibility,
bool has_snapshot_data,
uint64_t size,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle)
: Blob(std::move(blob_data_handle)),
has_backing_file_(!path.IsEmpty() || !relative_path.IsEmpty()),
user_visibility_(user_visibility),
path_(path),
name_(name),
- snapshot_modification_time_ms_(has_snapshot_data ? last_modified
- : InvalidFileTime()),
+ snapshot_modification_time_(last_modified),
relative_path_(relative_path) {
if (has_snapshot_data)
snapshot_size_ = size;
}
File::File(const String& name,
- double modification_time_ms,
+ const base::Optional<base::Time>& modification_time,
scoped_refptr<BlobDataHandle> blob_data_handle)
: Blob(std::move(blob_data_handle)),
has_backing_file_(false),
user_visibility_(File::kIsNotUserVisible),
name_(name),
snapshot_size_(Blob::size()),
- snapshot_modification_time_ms_(modification_time_ms) {
+ snapshot_modification_time_(modification_time) {
uint64_t size = Blob::size();
if (size != std::numeric_limits<uint64_t>::max())
snapshot_size_ = size;
@@ -254,8 +256,7 @@
user_visibility_(user_visibility),
path_(metadata.platform_path),
name_(name),
- snapshot_modification_time_ms_(
- ToJsTimeOrNaN(metadata.modification_time)) {
+ snapshot_modification_time_(metadata.modification_time) {
if (metadata.length >= 0)
snapshot_size_ = metadata.length;
}
@@ -271,8 +272,7 @@
name_(DecodeURLEscapeSequences(file_system_url.LastPathComponent(),
DecodeURLMode::kUTF8OrIsomorphic)),
file_system_url_(file_system_url),
- snapshot_modification_time_ms_(
- ToJsTimeOrNaN(metadata.modification_time)) {
+ snapshot_modification_time_(metadata.modification_time) {
if (metadata.length >= 0)
snapshot_size_ = metadata.length;
}
@@ -285,7 +285,7 @@
name_(other.name_),
file_system_url_(other.file_system_url_),
snapshot_size_(other.snapshot_size_),
- snapshot_modification_time_ms_(other.snapshot_modification_time_ms_),
+ snapshot_modification_time_(other.snapshot_modification_time_),
relative_path_(other.relative_path_) {}
File* File::Clone(const String& name) const {
@@ -295,49 +295,31 @@
return file;
}
-double File::LastModifiedMS() const {
- if (HasValidSnapshotMetadata() &&
- IsValidFileTime(snapshot_modification_time_ms_))
- return snapshot_modification_time_ms_;
+base::Time File::LastModifiedTime() const {
+ if (HasValidSnapshotMetadata() && snapshot_modification_time_)
+ return *snapshot_modification_time_;
base::Optional<base::Time> modification_time;
if (HasBackingFile() && GetFileModificationTime(path_, modification_time) &&
modification_time)
- return modification_time->ToJsTimeIgnoringNull();
+ return *modification_time;
- return base::Time::Now().ToDoubleT() * 1000.0;
+ // lastModified / lastModifiedDate getters should return the current time
+ // when the last modification time isn't known.
+ return base::Time::Now();
}
int64_t File::lastModified() const {
- double modified_date = LastModifiedMS();
-
- // The getter should return the current time when the last modification time
- // isn't known.
- if (!IsValidFileTime(modified_date))
- modified_date = base::Time::Now().ToDoubleT() * 1000.0;
-
// lastModified returns a number, not a Date instance,
// http://dev.w3.org/2006/webapi/FileAPI/#file-attrs
- return floor(modified_date);
+ return (LastModifiedTime() - base::Time::UnixEpoch()).InMilliseconds();
}
ScriptValue File::lastModifiedDate(ScriptState* script_state) const {
// lastModifiedDate returns a Date instance,
// http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate
- return ScriptValue(
- script_state->GetIsolate(),
- ToV8(base::Time::FromJsTime(LastModifiedDate()), script_state));
-}
-
-double File::LastModifiedDate() const {
- double modified_date = LastModifiedMS();
-
- // The getter should return the current time when the last modification time
- // isn't known.
- if (!IsValidFileTime(modified_date))
- modified_date = base::Time::Now().ToDoubleT() * 1000.0;
-
- return modified_date;
+ return ScriptValue(script_state->GetIsolate(),
+ ToV8(LastModifiedTime(), script_state));
}
uint64_t File::size() const {
@@ -380,8 +362,7 @@
base::Optional<base::Time>& snapshot_modification_time) const {
if (HasValidSnapshotMetadata()) {
snapshot_size = *snapshot_size_;
- snapshot_modification_time =
- JsTimeToOptionalTime(snapshot_modification_time_ms_);
+ snapshot_modification_time = snapshot_modification_time_;
return;
}
diff --git a/third_party/blink/renderer/core/fileapi/file.h b/third_party/blink/renderer/core/fileapi/file.h
index acd4d5ad..93aae77 100644
--- a/third_party/blink/renderer/core/fileapi/file.h
+++ b/third_party/blink/renderer/core/fileapi/file.h
@@ -26,7 +26,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_H_
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
+#include "base/time/time.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
@@ -74,7 +77,7 @@
UserVisibility user_visibility,
bool has_snapshot_data,
uint64_t size,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle) {
return MakeGarbageCollected<File>(
path, name, relative_path, user_visibility, has_snapshot_data, size,
@@ -84,7 +87,7 @@
const String& path,
const String& name,
uint64_t size,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle) {
return MakeGarbageCollected<File>(path, name, String(), kIsNotUserVisible,
true, size, last_modified,
@@ -132,10 +135,10 @@
UserVisibility,
bool has_snapshot_data,
uint64_t size,
- double last_modified,
+ const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle>);
File(const String& name,
- double modification_time,
+ const base::Optional<base::Time>& modification_time,
scoped_refptr<BlobDataHandle>);
File(const String& name, const FileMetadata&, UserVisibility);
File(const KURL& file_system_url, const FileMetadata&, UserVisibility);
@@ -198,8 +201,6 @@
// Getter for the lastModifiedDate IDL attribute,
// http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate
ScriptValue lastModifiedDate(ScriptState* script_state) const;
- // Returns milliseconds from the Unix epoch.
- double LastModifiedDate() const;
UserVisibility GetUserVisibility() const { return user_visibility_; }
@@ -214,7 +215,7 @@
base::Optional<base::Time>& snapshot_modification_time) const;
// Returns true if this has a valid snapshot metadata
- // (i.e. m_snapshotSize >= 0).
+ // (i.e. snapshot_size_.has_value()).
bool HasValidSnapshotMetadata() const { return snapshot_size_.has_value(); }
// Returns true if the sources (file path, file system URL, or blob handler)
@@ -227,9 +228,9 @@
private:
void InvalidateSnapshotMetadata() { snapshot_size_.reset(); }
- // Returns File's last modified time (in MS since Epoch.)
+ // Returns File's last modified time.
// If the modification time isn't known, the current time is returned.
- double LastModifiedMS() const;
+ base::Time LastModifiedTime() const;
#if DCHECK_IS_ON()
// Instances backed by a file must have an empty file system URL.
@@ -247,14 +248,22 @@
KURL file_system_url_;
- // If m_snapshotSize is negative (initialized to -1 by default), the snapshot
- // metadata is invalid and we retrieve the latest metadata synchronously in
- // size(), lastModifiedTime() and slice().
+ // If snapshot_size_ has no value, the snapshot metadata is invalid and
+ // we retrieve the latest metadata synchronously in size(),
+ // LastModifiedTime() and slice().
// Otherwise, the snapshot metadata are used directly in those methods.
base::Optional<uint64_t> snapshot_size_;
- const double snapshot_modification_time_ms_;
+ const base::Optional<base::Time> snapshot_modification_time_;
String relative_path_;
+
+ FRIEND_TEST_ALL_PREFIXES(FileTest, NativeFileWithoutTimestamp);
+ FRIEND_TEST_ALL_PREFIXES(FileTest, NativeFileWithUnixEpochTimestamp);
+ FRIEND_TEST_ALL_PREFIXES(FileTest, NativeFileWithApocalypseTimestamp);
+ FRIEND_TEST_ALL_PREFIXES(V8ScriptValueSerializerTest,
+ DecodeFileV4WithSnapshot);
+ FRIEND_TEST_ALL_PREFIXES(V8ScriptValueSerializerTest,
+ DecodeFileV8WithSnapshot);
};
template <>
diff --git a/third_party/blink/renderer/core/fileapi/file_list_test.cc b/third_party/blink/renderer/core/fileapi/file_list_test.cc
index a616fce..6190cc6 100644
--- a/third_party/blink/renderer/core/fileapi/file_list_test.cc
+++ b/third_party/blink/renderer/core/fileapi/file_list_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/fileapi/file_list.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
@@ -18,7 +19,8 @@
// Blob file.
const scoped_refptr<BlobDataHandle> blob_data_handle =
BlobDataHandle::Create();
- file_list->Append(MakeGarbageCollected<File>("name", 0.0, blob_data_handle));
+ file_list->Append(MakeGarbageCollected<File>("name", base::Time::UnixEpoch(),
+ blob_data_handle));
// User visible snapshot file.
{
diff --git a/third_party/blink/renderer/core/fileapi/file_test.cc b/third_party/blink/renderer/core/fileapi/file_test.cc
index e787a5e..e9ecaf11 100644
--- a/third_party/blink/renderer/core/fileapi/file_test.cc
+++ b/third_party/blink/renderer/core/fileapi/file_test.cc
@@ -53,16 +53,6 @@
base::File::Info file_info_;
};
-void ExpectLastModifiedIsNow(const File& file) {
- const base::Time now = base::Time::Now();
- const base::Time epoch = base::Time::UnixEpoch();
- // Because lastModified() applies floor() internally, it can be smaller than
- // |now|. |+ 1| adjusts it.
- EXPECT_GE(epoch + base::TimeDelta::FromMilliseconds(file.lastModified() + 1),
- now);
- EXPECT_GE(file.LastModifiedDate() + 1, now.ToJsTime());
-}
-
} // namespace
TEST(FileTest, NativeFileWithoutTimestamp) {
@@ -75,7 +65,13 @@
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ("/native/path", file->GetPath());
EXPECT_TRUE(file->FileSystemURL().IsEmpty());
- ExpectLastModifiedIsNow(*file);
+
+ const base::Time now = base::Time::Now();
+ const base::TimeDelta delta_now = now - base::Time::UnixEpoch();
+ // Because lastModified() applies floor() internally, we should compare
+ // integral millisecond values.
+ EXPECT_GE(file->lastModified(), delta_now.InMilliseconds());
+ EXPECT_GE(file->LastModifiedTime(), now);
}
TEST(FileTest, NativeFileWithUnixEpochTimestamp) {
@@ -87,7 +83,7 @@
auto* const file = MakeGarbageCollected<File>("/native/path");
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ(0, file->lastModified());
- EXPECT_EQ(0.0, file->LastModifiedDate());
+ EXPECT_EQ(base::Time::UnixEpoch(), file->LastModifiedTime());
}
TEST(FileTest, NativeFileWithApocalypseTimestamp) {
@@ -99,16 +95,16 @@
auto* const file = MakeGarbageCollected<File>("/native/path");
EXPECT_TRUE(file->HasBackingFile());
- ExpectLastModifiedIsNow(*file);
- // Actually, the timestamp should not be |now|.
- // EXPECT_EQ(base::Time::Max() - base::Time::UnixEpoch(),
- // base::TimeDelta::FromMilliseconds(file->lastModified()));
+ EXPECT_EQ((base::Time::Max() - base::Time::UnixEpoch()).InMilliseconds(),
+ file->lastModified());
+ EXPECT_EQ(base::Time::Max(), file->LastModifiedTime());
}
TEST(FileTest, blobBackingFile) {
const scoped_refptr<BlobDataHandle> blob_data_handle =
BlobDataHandle::Create();
- auto* const file = MakeGarbageCollected<File>("name", 0.0, blob_data_handle);
+ auto* const file = MakeGarbageCollected<File>("name", base::Time::UnixEpoch(),
+ blob_data_handle);
EXPECT_FALSE(file->HasBackingFile());
EXPECT_TRUE(file->GetPath().IsEmpty());
EXPECT_TRUE(file->FileSystemURL().IsEmpty());
@@ -152,12 +148,13 @@
const scoped_refptr<BlobDataHandle> blob_data_a = BlobDataHandle::Create();
const scoped_refptr<BlobDataHandle> blob_data_b = BlobDataHandle::Create();
+ const base::Time kEpoch = base::Time::UnixEpoch();
auto* const blob_file_a1 =
- MakeGarbageCollected<File>("name", 0.0, blob_data_a);
+ MakeGarbageCollected<File>("name", kEpoch, blob_data_a);
auto* const blob_file_a2 =
- MakeGarbageCollected<File>("name", 0.0, blob_data_a);
+ MakeGarbageCollected<File>("name", kEpoch, blob_data_a);
auto* const blob_file_b =
- MakeGarbageCollected<File>("name", 0.0, blob_data_b);
+ MakeGarbageCollected<File>("name", kEpoch, blob_data_b);
KURL url_a("filesystem:http://example.com/isolated/hash/non-native-file-A");
KURL url_b("filesystem:http://example.com/isolated/hash/non-native-file-B");
diff --git a/third_party/blink/renderer/core/html/forms/form_data.cc b/third_party/blink/renderer/core/html/forms/form_data.cc
index 8083925..4ef6dba 100644
--- a/third_party/blink/renderer/core/html/forms/form_data.cc
+++ b/third_party/blink/renderer/core/html/forms/form_data.cc
@@ -360,8 +360,7 @@
String filename = filename_;
if (filename.IsNull())
filename = "blob";
- return MakeGarbageCollected<File>(filename,
- base::Time::Now().ToDoubleT() * 1000.0,
+ return MakeGarbageCollected<File>(filename, base::Time::Now(),
GetBlob()->GetBlobDataHandle());
}
diff --git a/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc b/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
index 535c082..369ebd2a 100644
--- a/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
+++ b/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc
@@ -83,11 +83,8 @@
native_file_system_error::Reject(resolver, *result);
return;
}
- double last_modified = info.last_modified.is_null()
- ? InvalidFileTime()
- : info.last_modified.ToJsTime();
- resolver->Resolve(
- MakeGarbageCollected<File>(name, last_modified, blob));
+ resolver->Resolve(MakeGarbageCollected<File>(
+ name, NullableTimeToOptionalTime(info.last_modified), blob));
},
WrapPersistent(resolver), name()));
diff --git a/third_party/blink/renderer/platform/file_metadata.h b/third_party/blink/renderer/platform/file_metadata.h
index 162b95c..08c52dd 100644
--- a/third_party/blink/renderer/platform/file_metadata.h
+++ b/third_party/blink/renderer/platform/file_metadata.h
@@ -41,15 +41,6 @@
namespace blink {
-// TODO(crbug.com/988343): InvalidFileTime() and IsValidFileTime() should be
-// removed. File timestamps should be represented as base::Optional<base::Time>.
-inline double InvalidFileTime() {
- return std::numeric_limits<double>::quiet_NaN();
-}
-inline bool IsValidFileTime(double time) {
- return std::isfinite(time);
-}
-
class FileMetadata {
DISALLOW_NEW();
@@ -81,20 +72,6 @@
PLATFORM_EXPORT void RebindFileUtilitiesForTesting();
-// TODO(crbug.com/988343): Temporary conversion function. This should be
-// removed.
-inline double ToJsTimeOrNaN(base::Optional<base::Time> time) {
- return time ? time->ToJsTimeIgnoringNull() : InvalidFileTime();
-}
-
-// TODO(crbug.com/988343): Temporary conversion function. This should be
-// removed.
-inline base::Optional<base::Time> JsTimeToOptionalTime(double ms) {
- if (!IsValidFileTime(ms))
- return base::nullopt;
- return base::Time::FromJsTime(ms);
-}
-
inline base::Optional<base::Time> NullableTimeToOptionalTime(base::Time time) {
if (time.is_null())
return base::nullopt;