Import Cobalt 20.master.0.234144

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/5590
  by n1214.hwang@samsung.com

  https://cobalt-review.googlesource.com/c/cobalt/+/5530
  by errong.leng@samsung.com

  https://cobalt-review.googlesource.com/c/cobalt/+/5570
  by devin.cai@mediatek.com
diff --git a/src/base/base.gyp b/src/base/base.gyp
index 9cbd82f..5eccf13 100644
--- a/src/base/base.gyp
+++ b/src/base/base.gyp
@@ -142,6 +142,8 @@
         'files/file_util.cc',
         'files/file_util.h',
         'files/file_util_starboard.cc',
+        'files/important_file_writer.cc',
+        'files/important_file_writer.h',
         'files/platform_file.h',
         'files/scoped_file.cc',
         'files/scoped_file.h',
@@ -773,6 +775,7 @@
         'files/file_proxy_unittest.cc',
         'files/file_unittest.cc',
         'files/file_util_unittest.cc',
+        'files/important_file_writer_unittest.cc',
         'files/scoped_temp_dir_unittest.cc',
         'gmock_unittest.cc',
         'guid_unittest.cc',
diff --git a/src/base/cpp14oncpp11.h b/src/base/cpp14oncpp11.h
index bc791ea..ae23cd3 100644
--- a/src/base/cpp14oncpp11.h
+++ b/src/base/cpp14oncpp11.h
@@ -162,45 +162,55 @@
 template<typename T>
 using add_volatile_t = typename add_volatile<T>::type;
 
-template< class C > 
+template< class C >
 auto rbegin( C& c ) -> decltype(c.rbegin()) {
   return c.rbegin();
 }
 
-template< class C > 
+template< class C >
 auto rbegin( const C& c ) -> decltype(c.rbegin()) {
   return c.rbegin();
 }
 
-template< class T, size_t N > 
+template< class T, size_t N >
 reverse_iterator<T*> rbegin( T (&array)[N] ) {
   return reverse_iterator<T*>(array + N);
 }
 
-template< class C > 
+template <class C>
+constexpr auto cbegin(const C& c) -> decltype(std::begin(c)) {
+  return std::begin(c);
+}
+
+template< class C >
 auto crbegin( const C& c ) -> decltype(std::rbegin(c)) {
   return std::rbegin(c);
 }
 
-template< class C > 
+template< class C >
 auto rend( C& c ) -> decltype(c.rend()) {
   return c.rend();
 }
 
-template< class C > 
+template< class C >
 auto rend( const C& c ) -> decltype(c.rend()) {
   return c.rend();
 }
 
-template< class T, size_t N > 
+template< class T, size_t N >
 reverse_iterator<T*> rend( T (&array)[N] ) {
   return reverse_iterator<T*>(array);
 }
 
-template< class C > 
+template< class C >
 auto crend( const C& c ) -> decltype(std::rend(c)) {
   return std::rend(c);
 }
+
+template <class C>
+constexpr auto cend(const C& c) -> decltype(std::end(c)) {
+  return std::end(c);
+}
 #endif
 
 }  // namespace std
diff --git a/src/base/files/important_file_writer.cc b/src/base/files/important_file_writer.cc
index c5a120f..968c753 100644
--- a/src/base/files/important_file_writer.cc
+++ b/src/base/files/important_file_writer.cc
@@ -27,6 +27,7 @@
 #include "base/threading/thread.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "starboard/file.h"
 #include "starboard/types.h"
 
 namespace base {
@@ -130,6 +131,22 @@
 
 }  // namespace
 
+#if defined(OS_STARBOARD)
+// static
+bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
+                                              StringPiece data,
+                                              StringPiece histogram_suffix) {
+  SB_UNREFERENCED_PARAMETER(histogram_suffix);
+#if SB_API_VERSION >= SB_FILE_ATOMIC_REPLACE_VERSION
+  return SbFileAtomicReplace(path.value().c_str(), data.data(), data.size());
+#else
+  SB_NOTREACHED()
+      << "SbFileAtomicReplace is not available before starboard version "
+      << SB_FILE_ATOMIC_REPLACE_VERSION;
+  return false;
+#endif
+}
+#else
 // static
 bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
                                               StringPiece data,
@@ -210,6 +227,7 @@
 
   return true;
 }
+#endif
 
 ImportantFileWriter::ImportantFileWriter(
     const FilePath& path,
diff --git a/src/base/files/important_file_writer.h b/src/base/files/important_file_writer.h
index 386811a..f0cbfd2 100644
--- a/src/base/files/important_file_writer.h
+++ b/src/base/files/important_file_writer.h
@@ -17,8 +17,6 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 
-#if !defined(STARBOARD)
-
 namespace base {
 
 class SequencedTaskRunner;
@@ -160,6 +158,4 @@
 
 }  // namespace base
 
-#endif  // #if !defined(STARBOARD)
-
 #endif  // BASE_FILES_IMPORTANT_FILE_WRITER_H_
diff --git a/src/base/files/important_file_writer_unittest.cc b/src/base/files/important_file_writer_unittest.cc
index 5dddc71..680a2f8 100644
--- a/src/base/files/important_file_writer_unittest.cc
+++ b/src/base/files/important_file_writer_unittest.cc
@@ -23,6 +23,7 @@
 #include "base/timer/mock_timer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if SB_API_VERSION >= SB_FILE_ATOMIC_REPLACE_VERSION
 namespace base {
 
 namespace {
@@ -179,6 +180,9 @@
   EXPECT_EQ("baz", GetFileContent(writer.path()));
 }
 
+// Disable the test as win32 SbFileOpen doesn't fail on relative path
+// like bad/../path.tmp
+#if !defined(OS_STARBOARD)
 TEST_F(ImportantFileWriterTest, FailedWriteWithObserver) {
   // Use an invalid file path (relative paths are invalid) to get a
   // FILE_ERROR_ACCESS_DENIED error when trying to write the file.
@@ -196,6 +200,7 @@
             write_callback_observer_.GetAndResetObservationState());
   EXPECT_FALSE(PathExists(writer.path()));
 }
+#endif
 
 TEST_F(ImportantFileWriterTest, CallbackRunsOnWriterThread) {
   base::Thread file_writer_thread("ImportantFileWriter test thread");
@@ -327,6 +332,7 @@
   EXPECT_FALSE(PathExists(writer.path()));
 }
 
+#if !defined(OS_STARBOARD)
 TEST_F(ImportantFileWriterTest, WriteFileAtomicallyHistogramSuffixTest) {
   base::HistogramTester histogram_tester;
   EXPECT_FALSE(PathExists(file_));
@@ -347,5 +353,8 @@
   histogram_tester.ExpectTotalCount("ImportantFile.FileCreateError", 1);
   histogram_tester.ExpectTotalCount("ImportantFile.FileCreateError.test", 1);
 }
+#endif
 
 }  // namespace base
+
+#endif  // SB_API_VERSION >= SB_FILE_ATOMIC_REPLACE_VERSION
diff --git a/src/base/time/time.cc b/src/base/time/time.cc
index 90e22cc..b975053 100644
--- a/src/base/time/time.cc
+++ b/src/base/time/time.cc
@@ -30,7 +30,8 @@
 TimeTicksNowFunction g_time_ticks_now_function =
     &subtle::TimeTicksNowIgnoringOverride;
 
-#if SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION || \
+    SB_HAS(TIME_THREAD_NOW)
 ThreadTicksNowFunction g_thread_ticks_now_function =
     &subtle::ThreadTicksNowIgnoringOverride;
 #endif
@@ -323,11 +324,14 @@
 
 // static
 ThreadTicks ThreadTicks::Now() {
-#if SB_HAS(TIME_THREAD_NOW)
-  return internal::g_thread_ticks_now_function();
-#else
-  return ThreadTicks();
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION || \
+    SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION
+  if (SbTimeIsTimeThreadNowSupported())
 #endif
+    return internal::g_thread_ticks_now_function();
+#endif
+  return ThreadTicks();
 }
 
 std::ostream& operator<<(std::ostream& os, ThreadTicks thread_ticks) {
diff --git a/src/base/time/time.h b/src/base/time/time.h
index fba813a..8ee1b6d 100644
--- a/src/base/time/time.h
+++ b/src/base/time/time.h
@@ -997,7 +997,9 @@
   // Returns true if ThreadTicks::Now() is supported on this system.
   static bool IsSupported() WARN_UNUSED_RESULT {
 #if defined(STARBOARD)
-#if SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION
+    return SbTimeIsTimeThreadNowSupported();
+#elif SB_HAS(TIME_THREAD_NOW)
     return true;
 #else
     return false;
diff --git a/src/base/time/time_now_starboard.cc b/src/base/time/time_now_starboard.cc
index f876e9c..e80ffaf 100644
--- a/src/base/time/time_now_starboard.cc
+++ b/src/base/time/time_now_starboard.cc
@@ -62,12 +62,15 @@
 
 namespace subtle {
 ThreadTicks ThreadTicksNowIgnoringOverride() {
-#if SB_HAS(TIME_THREAD_NOW)
-  return ThreadTicks() +
-         TimeDelta::FromMicroseconds(SbTimeGetMonotonicThreadNow());
-#else
-  return ThreadTicks();
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION || \
+    SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION
+  if (SbTimeIsTimeThreadNowSupported())
 #endif
+    return ThreadTicks() +
+           TimeDelta::FromMicroseconds(SbTimeGetMonotonicThreadNow());
+#endif
+  return ThreadTicks();
 }
 }  // namespace subtle
 
diff --git a/src/base/time/time_override.cc b/src/base/time/time_override.cc
index 6232bfe..63f4d8e 100644
--- a/src/base/time/time_override.cc
+++ b/src/base/time/time_override.cc
@@ -26,7 +26,8 @@
   }
   if (time_ticks_override)
     internal::g_time_ticks_now_function = time_ticks_override;
-#if SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION || \
+    SB_HAS(TIME_THREAD_NOW)
   if (thread_ticks_override)
     internal::g_thread_ticks_now_function = thread_ticks_override;
 #endif
@@ -37,7 +38,8 @@
   internal::g_time_now_from_system_time_function =
       &TimeNowFromSystemTimeIgnoringOverride;
   internal::g_time_ticks_now_function = &TimeTicksNowIgnoringOverride;
-#if SB_HAS(TIME_THREAD_NOW)
+#if SB_API_VERSION >= SB_TIME_THREAD_NOW_REQUIRED_VERSION || \
+    SB_HAS(TIME_THREAD_NOW)
   internal::g_thread_ticks_now_function = &ThreadTicksNowIgnoringOverride;
 #endif
 #if DCHECK_IS_ON()
diff --git a/src/base/trace_event/memory_usage_estimator.h b/src/base/trace_event/memory_usage_estimator.h
index 53ce8f7..24f144f 100644
--- a/src/base/trace_event/memory_usage_estimator.h
+++ b/src/base/trace_event/memory_usage_estimator.h
@@ -211,10 +211,12 @@
 struct EMUCaller {
   // std::is_same<> below makes static_assert depend on T, in order to
   // prevent it from asserting regardless instantiation.
+#if !defined(_GLIBCXX_DEBUG) && !defined(_LIBCPP_DEBUG)
   static_assert(std::is_same<T, std::false_type>::value,
                 "Neither global function 'size_t EstimateMemoryUsage(T)' "
                 "nor member function 'size_t T::EstimateMemoryUsage() const' "
                 "is defined for the type.");
+#endif
 
   static size_t Call(const T&) { return 0; }
 };
diff --git a/src/base/util/values/values_util.cc b/src/base/util/values/values_util.cc
new file mode 100644
index 0000000..43b317b
--- /dev/null
+++ b/src/base/util/values/values_util.cc
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/util/values/values_util.h"
+
+#include "base/strings/string_number_conversions.h"
+
+namespace util {
+
+base::Value Int64ToValue(int64_t integer) {
+  return base::Value(base::NumberToString(integer));
+}
+
+base::Optional<int64_t> ValueToInt64(const base::Value* value) {
+  return value ? ValueToInt64(*value) : base::nullopt;
+}
+
+base::Optional<int64_t> ValueToInt64(const base::Value& value) {
+  if (!value.is_string())
+    return base::nullopt;
+
+  int64_t integer;
+  if (!base::StringToInt64(value.GetString(), &integer))
+    return base::nullopt;
+
+  return integer;
+}
+
+base::Value TimeDeltaToValue(base::TimeDelta time_delta) {
+  return Int64ToValue(time_delta.InMicroseconds());
+}
+
+base::Optional<base::TimeDelta> ValueToTimeDelta(const base::Value* value) {
+  return value ? ValueToTimeDelta(*value) : base::nullopt;
+}
+
+base::Optional<base::TimeDelta> ValueToTimeDelta(const base::Value& value) {
+  base::Optional<int64_t> integer = ValueToInt64(value);
+  if (!integer)
+    return base::nullopt;
+  return base::TimeDelta::FromMicroseconds(*integer);
+}
+
+base::Value TimeToValue(base::Time time) {
+  return TimeDeltaToValue(time.ToDeltaSinceWindowsEpoch());
+}
+
+base::Optional<base::Time> ValueToTime(const base::Value* value) {
+  return value ? ValueToTime(*value) : base::nullopt;
+}
+
+base::Optional<base::Time> ValueToTime(const base::Value& value) {
+  base::Optional<base::TimeDelta> time_delta = ValueToTimeDelta(value);
+  if (!time_delta)
+    return base::nullopt;
+  return base::Time::FromDeltaSinceWindowsEpoch(*time_delta);
+}
+
+}  // namespace util
diff --git a/src/base/util/values/values_util.gyp b/src/base/util/values/values_util.gyp
new file mode 100644
index 0000000..0c537c0
--- /dev/null
+++ b/src/base/util/values/values_util.gyp
@@ -0,0 +1,29 @@
+# Copyright 2019 The Cobalt Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+{
+  'targets': [
+    {
+      'target_name': 'values_util',
+      'type': 'static_library',
+      'sources': [
+        'values_util.cc',
+        'values_util.h',
+      ],
+      'dependencies': [
+        '<(DEPTH)/base/base.gyp:base',
+      ],
+    },
+  ]
+}
diff --git a/src/base/util/values/values_util.h b/src/base/util/values/values_util.h
new file mode 100644
index 0000000..de9fd1b
--- /dev/null
+++ b/src/base/util/values/values_util.h
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_UTIL_VALUES_VALUES_UTIL_H_
+#define BASE_UTIL_VALUES_VALUES_UTIL_H_
+
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "base/values.h"
+
+namespace util {
+
+// Simple helper functions for converting int64_t, base::TimeDelta and
+// base::Time to numeric string base::Values.
+// Because base::TimeDelta and base::Time share the same internal representation
+// as int64_t they are stored using the exact same numeric string format.
+
+// Stores the int64_t as a string.
+base::Value Int64ToValue(int64_t integer);
+base::Optional<int64_t> ValueToInt64(const base::Value* value);
+base::Optional<int64_t> ValueToInt64(const base::Value& value);
+
+// Converts the TimeDelta to an int64_t of microseconds.
+base::Value TimeDeltaToValue(base::TimeDelta time_delta);
+base::Optional<base::TimeDelta> ValueToTimeDelta(const base::Value* value);
+base::Optional<base::TimeDelta> ValueToTimeDelta(const base::Value& value);
+
+// Converts the Time to a TimeDelta from the Windows epoch.
+base::Value TimeToValue(base::Time time);
+base::Optional<base::Time> ValueToTime(const base::Value* value);
+base::Optional<base::Time> ValueToTime(const base::Value& value);
+
+}  // namespace util
+
+#endif  // BASE_UTIL_VALUES_VALUES_UTIL_H_