summaryrefslogtreecommitdiffstats
path: root/libchrome_tools
diff options
context:
space:
mode:
authorHidehiko Abe <hidehiko@google.com>2018-03-12 17:15:45 +0900
committerHidehiko Abe <hidehiko@google.com>2018-03-13 18:29:05 +0900
commitb912d92fdb4d105106904cbff5424e129e5398e3 (patch)
treeec51143c1f3a9052e694afb4698c6d41c975aba4 /libchrome_tools
parentb1919cfb4a2ec955423e6cf8ccc6afabc8ffb3ed (diff)
downloadplatform_external_libchrome-b912d92fdb4d105106904cbff5424e129e5398e3.tar.gz
platform_external_libchrome-b912d92fdb4d105106904cbff5424e129e5398e3.tar.bz2
platform_external_libchrome-b912d92fdb4d105106904cbff5424e129e5398e3.zip
Introduce update_libchrome.py.
Now we can uprev the libchrome by the script, except; - patch conflict - new change which needs to be patched, and - client code change. Bug: 72617985 Test: Ran update_libchrome.py, and made sure no diff. Change-Id: I03c0544995a3e68ad90fbf45999ecf01a7c8b0f8
Diffstat (limited to 'libchrome_tools')
-rw-r--r--libchrome_tools/patch/allocator_shim.patch13
-rw-r--r--libchrome_tools/patch/ashmem.patch20
-rw-r--r--libchrome_tools/patch/build_config.patch56
-rw-r--r--libchrome_tools/patch/build_time.patch74
-rw-r--r--libchrome_tools/patch/buildflag_header.patch32
-rw-r--r--libchrome_tools/patch/compiler_specific.patch16
-rw-r--r--libchrome_tools/patch/dmg_fp.patch156
-rw-r--r--libchrome_tools/patch/file_posix.patch15
-rw-r--r--libchrome_tools/patch/gmock.patch6
-rw-r--r--libchrome_tools/patch/gtest.patch10
-rw-r--r--libchrome_tools/patch/hash.patch28
-rw-r--r--libchrome_tools/patch/lazy_instance.patch18
-rw-r--r--libchrome_tools/patch/libevent.patch13
-rw-r--r--libchrome_tools/patch/logging.patch80
-rw-r--r--libchrome_tools/patch/macros.patch69
-rw-r--r--libchrome_tools/patch/message_loop.patch13
-rw-r--r--libchrome_tools/patch/modp_b64.patch19
-rw-r--r--libchrome_tools/patch/path_service.patch92
-rw-r--r--libchrome_tools/patch/protobuf.patch4
-rw-r--r--libchrome_tools/patch/shared_memory_posix.patch56
-rw-r--r--libchrome_tools/patch/ssl.patch126
-rw-r--r--libchrome_tools/patch/stack_trace_posix.patch45
-rw-r--r--libchrome_tools/patch/statfs_f_type.patch40
-rw-r--r--libchrome_tools/patch/subprocess.patch74
-rw-r--r--libchrome_tools/patch/symbolize.patch18
-rw-r--r--libchrome_tools/patch/task_scheduler.patch152
-rw-r--r--libchrome_tools/patch/time.patch19
-rw-r--r--libchrome_tools/patch/valgrind.patch33
-rw-r--r--libchrome_tools/patch/virtual_destructor.patch78
-rw-r--r--libchrome_tools/update_libchrome.py158
30 files changed, 1533 insertions, 0 deletions
diff --git a/libchrome_tools/patch/allocator_shim.patch b/libchrome_tools/patch/allocator_shim.patch
new file mode 100644
index 000000000..e87f614ec
--- /dev/null
+++ b/libchrome_tools/patch/allocator_shim.patch
@@ -0,0 +1,13 @@
+# Use allocator_shim_override_linker_wrapped_symbols.h for ANDROID.
+
+--- a/base/allocator/allocator_shim.cc
++++ b/base/allocator/allocator_shim.cc
+@@ -299,7 +299,7 @@ ALWAYS_INLINE void ShimFreeDefiniteSize(
+ #include "base/allocator/allocator_shim_override_cpp_symbols.h"
+ #endif
+
+-#if defined(OS_ANDROID)
++#if defined(OS_ANDROID) || defined(ANDROID)
+ // Android does not support symbol interposition. The way malloc symbols are
+ // intercepted on Android is by using link-time -wrap flags.
+ #include "base/allocator/allocator_shim_override_linker_wrapped_symbols.h"
diff --git a/libchrome_tools/patch/ashmem.patch b/libchrome_tools/patch/ashmem.patch
new file mode 100644
index 000000000..c59a53677
--- /dev/null
+++ b/libchrome_tools/patch/ashmem.patch
@@ -0,0 +1,20 @@
+--- /dev/null
++++ b/third_party/ashmem/ashmem.h
+@@ -0,0 +1,17 @@
++// Copyright (C) 2018 The Android Open Source Project
++//
++// 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.
++
++// third_party/ashmem is Android shared memory. Instead of clone it here,
++// use cutils/ashmem.h directly.
++#include <cutils/ashmem.h>
diff --git a/libchrome_tools/patch/build_config.patch b/libchrome_tools/patch/build_config.patch
new file mode 100644
index 000000000..d22e93592
--- /dev/null
+++ b/libchrome_tools/patch/build_config.patch
@@ -0,0 +1,56 @@
+--- a/build/build_config.h
++++ b/build/build_config.h
+@@ -16,6 +16,43 @@
+ #ifndef BUILD_BUILD_CONFIG_H_
+ #define BUILD_BUILD_CONFIG_H_
+
++// A brief primer on #defines:
++//
++// - __ANDROID__ is automatically defined by the Android toolchain (see
++// https://goo.gl/v61lXa). It's not defined when building host code.
++// - __ANDROID_HOST__ is defined via -D by Android.mk when building host code
++// within an Android checkout.
++// - ANDROID is defined via -D when building code for either Android targets or
++// hosts. Use __ANDROID__ and __ANDROID_HOST__ instead.
++// - OS_ANDROID is a Chrome-specific define used to build Chrome for Android
++// within the NDK.
++
++// Android targets and hosts don't use tcmalloc.
++#if defined(__ANDROID__) || defined(__ANDROID_HOST__)
++#define NO_TCMALLOC
++#endif // defined(__ANDROID__) || defined(__ANDROID_HOST__)
++
++// Use the Chrome OS version of the code for both Android targets and Chrome OS builds.
++#if !defined(__ANDROID_HOST__)
++#define OS_CHROMEOS 1
++#endif // !defined(__ANDROID_HOST__)
++
++#if defined(__ANDROID__) // Android targets
++
++#define __linux__ 1
++#if defined(__BIONIC__)
++#define __UCLIBC__ 1
++#endif // defined(__BIONIC__)
++
++#elif !defined(__ANDROID_HOST__) // Chrome OS
++
++// TODO: Remove these once the GLib MessageLoopForUI isn't being used:
++// https://crbug.com/361635
++#define USE_GLIB 1
++#define USE_OZONE 1
++
++#endif // defined(__ANDROID__)
++
+ // A set of macros to use for platform detection.
+ #if defined(__native_client__)
+ // __native_client__ must be first, so that other OS_ defines are not set.
+@@ -28,8 +65,7 @@
+ #else
+ #define OS_NACL_SFI
+ #endif
+-#elif defined(ANDROID)
+-#define OS_ANDROID 1
++// Don't set OS_ANDROID; it's only used when building Chrome for Android.
+ #elif defined(__APPLE__)
+ // only include TargetConditions after testing ANDROID as some android builds
+ // on mac don't have this header available and it's not needed unless the target
diff --git a/libchrome_tools/patch/build_time.patch b/libchrome_tools/patch/build_time.patch
new file mode 100644
index 000000000..cebe8a6f1
--- /dev/null
+++ b/libchrome_tools/patch/build_time.patch
@@ -0,0 +1,74 @@
+--- a/base/build_time.cc
++++ b/base/build_time.cc
+@@ -4,20 +4,31 @@
+
+ #include "base/build_time.h"
+
+-// Imports the generated build date, i.e. BUILD_DATE.
+-#include "base/generated_build_date.h"
+-
+ #include "base/logging.h"
+ #include "base/time/time.h"
+
++#ifdef __ANDROID__
++#include <cutils/properties.h>
++#endif
++
+ namespace base {
+
+ Time GetBuildTime() {
+ Time integral_build_time;
+- // BUILD_DATE is exactly "Mmm DD YYYY HH:MM:SS".
+- // See //build/write_build_date_header.py. "HH:MM:SS" is normally expected to
+- // be "05:00:00" but is not enforced here.
+- bool result = Time::FromUTCString(BUILD_DATE, &integral_build_time);
++ // The format of __DATE__ and __TIME__ is specified by the ANSI C Standard,
++ // section 6.8.8.
++ //
++ // __DATE__ is exactly "Mmm DD YYYY".
++ // __TIME__ is exactly "hh:mm:ss".
++#if defined(__ANDROID__)
++ char kDateTime[PROPERTY_VALUE_MAX];
++ property_get("ro.build.date", kDateTime, "Sep 02 2008 08:00:00 PST");
++#elif defined(DONT_EMBED_BUILD_METADATA) && !defined(OFFICIAL_BUILD)
++ const char kDateTime[] = "Sep 02 2008 08:00:00 PST";
++#else
++ const char kDateTime[] = __DATE__ " " __TIME__ " PST";
++#endif
++ bool result = Time::FromString(kDateTime, &integral_build_time);
+ DCHECK(result);
+ return integral_build_time;
+ }
+--- a/base/build_time_unittest.cc
++++ b/base/build_time_unittest.cc
+@@ -3,13 +3,19 @@
+ // found in the LICENSE file.
+
+ #include "base/build_time.h"
++#if !defined(DONT_EMBED_BUILD_METADATA)
+ #include "base/generated_build_date.h"
++#endif
+ #include "base/time/time.h"
+
+ #include "testing/gtest/include/gtest/gtest.h"
+
+ TEST(BuildTime, DateLooksValid) {
++#if !defined(DONT_EMBED_BUILD_METADATA)
+ char build_date[] = BUILD_DATE;
++#else
++ char build_date[] = "Sep 02 2008 05:00:00";
++#endif
+
+ EXPECT_EQ(20u, strlen(build_date));
+ EXPECT_EQ(' ', build_date[3]);
+@@ -30,8 +36,10 @@ TEST(BuildTime, InThePast) {
+ EXPECT_LT(base::GetBuildTime(), base::Time::NowFromSystemTime());
+ }
+
++#if !defined(DONT_EMBED_BUILD_METADATA)
+ TEST(BuildTime, NotTooFar) {
+ // BuildTime must be less than 45 days old.
+ base::Time cutoff(base::Time::Now() - base::TimeDelta::FromDays(45));
+ EXPECT_GT(base::GetBuildTime(), cutoff);
+ }
++#endif
diff --git a/libchrome_tools/patch/buildflag_header.patch b/libchrome_tools/patch/buildflag_header.patch
new file mode 100644
index 000000000..69cc417b7
--- /dev/null
+++ b/libchrome_tools/patch/buildflag_header.patch
@@ -0,0 +1,32 @@
+# These files are generated by buildflag_header rule in Chromium.
+# Instead, in libchrome, these are checked in.
+
+--- /dev/null
++++ b/base/allocator/features.h
+@@ -0,0 +1,15 @@
++// Generated by build/write_buildflag_header.py
++// From "allocator_features"
++
++#ifndef BASE_ALLOCATOR_FEATURES_H_
++#define BASE_ALLOCATOR_FEATURES_H_
++
++#include "build/buildflag.h"
++
++#if defined(__APPLE__) || defined(ANDROID)
++#define BUILDFLAG_INTERNAL_USE_EXPERIMENTAL_ALLOCATOR_SHIM() (0)
++#else
++#define BUILDFLAG_INTERNAL_USE_EXPERIMENTAL_ALLOCATOR_SHIM() (1)
++#endif
++
++#endif // BASE_ALLOCATOR_FEATURES_H_
+--- /dev/null
++++ b/base/debug/debugging_flags.h
+@@ -0,0 +1,8 @@
++// Generated by build/write_buildflag_header.py
++// From "base_debugging_flags"
++#ifndef BASE_DEBUG_DEBUGGING_FLAGS_H_
++#define BASE_DEBUG_DEBUGGING_FLAGS_H_
++#include "build/buildflag.h"
++#define BUILDFLAG_INTERNAL_ENABLE_PROFILING() (0)
++#define BUILDFLAG_INTERNAL_ENABLE_MEMORY_TASK_PROFILER() (0)
++#endif // BASE_DEBUG_DEBUGGING_FLAGS_H_
diff --git a/libchrome_tools/patch/compiler_specific.patch b/libchrome_tools/patch/compiler_specific.patch
new file mode 100644
index 000000000..87d7354c0
--- /dev/null
+++ b/libchrome_tools/patch/compiler_specific.patch
@@ -0,0 +1,16 @@
+# In Android, prefer Android's libbase definitions for LIKELY/UNLIKELY macros.
+
+--- a/base/compiler_specific.h
++++ b/base/compiler_specific.h
+@@ -7,6 +7,11 @@
+
+ #include "build/build_config.h"
+
++#if defined(ANDROID)
++// Prefer Android's libbase definitions to our own.
++#include <android-base/macros.h>
++#endif // defined(ANDROID)
++
+ #if defined(COMPILER_MSVC)
+
+ // For _Printf_format_string_.
diff --git a/libchrome_tools/patch/dmg_fp.patch b/libchrome_tools/patch/dmg_fp.patch
new file mode 100644
index 000000000..50427716c
--- /dev/null
+++ b/libchrome_tools/patch/dmg_fp.patch
@@ -0,0 +1,156 @@
+# Libchrome does not support/require dmg_fp library. Instead, use standard
+# library.
+
+--- a/base/strings/string_number_conversions.cc
++++ b/base/strings/string_number_conversions.cc
+@@ -15,7 +15,6 @@
+ #include "base/logging.h"
+ #include "base/numerics/safe_math.h"
+ #include "base/scoped_clear_errno.h"
+-#include "base/third_party/dmg_fp/dmg_fp.h"
+
+ namespace base {
+
+@@ -369,10 +368,18 @@ string16 SizeTToString16(size_t value) {
+ }
+
+ std::string DoubleToString(double value) {
+- // According to g_fmt.cc, it is sufficient to declare a buffer of size 32.
+- char buffer[32];
+- dmg_fp::g_fmt(buffer, value);
+- return std::string(buffer);
++ auto ret = std::to_string(value);
++ // If this returned an integer, don't do anything.
++ if (ret.find('.') == std::string::npos) {
++ return ret;
++ }
++ // Otherwise, it has an annoying tendency to leave trailing zeros.
++ size_t len = ret.size();
++ while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') {
++ --len;
++ }
++ ret.erase(len);
++ return ret;
+ }
+
+ bool StringToInt(const StringPiece& input, int* output) {
+@@ -416,14 +423,10 @@ bool StringToSizeT(const StringPiece16&
+ }
+
+ bool StringToDouble(const std::string& input, double* output) {
+- // Thread-safe? It is on at least Mac, Linux, and Windows.
+- ScopedClearErrno clear_errno;
+-
+- char* endptr = NULL;
+- *output = dmg_fp::strtod(input.c_str(), &endptr);
++ char* endptr = nullptr;
++ *output = strtod(input.c_str(), &endptr);
+
+ // Cases to return false:
+- // - If errno is ERANGE, there was an overflow or underflow.
+ // - If the input string is empty, there was nothing to parse.
+ // - If endptr does not point to the end of the string, there are either
+ // characters remaining in the string after a parsed number, or the string
+@@ -431,10 +434,11 @@ bool StringToDouble(const std::string& i
+ // expected end given the string's stated length to correctly catch cases
+ // where the string contains embedded NUL characters.
+ // - If the first character is a space, there was leading whitespace
+- return errno == 0 &&
+- !input.empty() &&
++ return !input.empty() &&
+ input.c_str() + input.length() == endptr &&
+- !isspace(input[0]);
++ !isspace(input[0]) &&
++ *output != std::numeric_limits<double>::infinity() &&
++ *output != -std::numeric_limits<double>::infinity();
+ }
+
+ // Note: if you need to add String16ToDouble, first ask yourself if it's
+--- a/base/strings/string_number_conversions.h
++++ b/base/strings/string_number_conversions.h
+@@ -54,6 +54,7 @@ BASE_EXPORT string16 Uint64ToString16(ui
+ BASE_EXPORT std::string SizeTToString(size_t value);
+ BASE_EXPORT string16 SizeTToString16(size_t value);
+
++// Deprecated: prefer std::to_string(double) instead.
+ // DoubleToString converts the double to a string format that ignores the
+ // locale. If you want to use locale specific formatting, use ICU.
+ BASE_EXPORT std::string DoubleToString(double value);
+@@ -91,6 +92,7 @@ BASE_EXPORT bool StringToUint64(const St
+ BASE_EXPORT bool StringToSizeT(const StringPiece& input, size_t* output);
+ BASE_EXPORT bool StringToSizeT(const StringPiece16& input, size_t* output);
+
++// Deprecated: prefer std::stod() instead.
+ // For floating-point conversions, only conversions of input strings in decimal
+ // form are defined to work. Behavior with strings representing floating-point
+ // numbers in hexadecimal, and strings representing non-finite values (such as
+--- a/base/strings/string_number_conversions_unittest.cc
++++ b/base/strings/string_number_conversions_unittest.cc
+@@ -752,20 +752,8 @@ TEST(StringNumberConversionsTest, String
+ {"9e999", HUGE_VAL, false},
+ {"9e1999", HUGE_VAL, false},
+ {"9e19999", HUGE_VAL, false},
+- {"9e99999999999999999999", HUGE_VAL, false},
+- {"-9e307", -9e307, true},
+- {"-1.7976e308", -1.7976e308, true},
+- {"-1.7977e308", -HUGE_VAL, false},
+- {"-1.797693134862315807e+308", -HUGE_VAL, true},
+- {"-1.797693134862315808e+308", -HUGE_VAL, false},
+- {"-9e308", -HUGE_VAL, false},
+- {"-9e309", -HUGE_VAL, false},
+- {"-9e999", -HUGE_VAL, false},
+- {"-9e1999", -HUGE_VAL, false},
+- {"-9e19999", -HUGE_VAL, false},
+- {"-9e99999999999999999999", -HUGE_VAL, false},
+-
+- // Test more exponents.
++ {"9e99999999999999999999", std::numeric_limits<double>::infinity(), false},
++ {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(), false},
+ {"1e-2", 0.01, true},
+ {"42 ", 42.0, false},
+ {" 1e-2", 0.01, false},
+@@ -795,7 +783,8 @@ TEST(StringNumberConversionsTest, String
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ double output;
+ errno = 1;
+- EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
++ EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output))
++ << "for input=" << cases[i].input << "got output=" << output;
+ if (cases[i].success)
+ EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged.
+ EXPECT_DOUBLE_EQ(cases[i].output, output);
+@@ -816,13 +805,13 @@ TEST(StringNumberConversionsTest, Double
+ double input;
+ const char* expected;
+ } cases[] = {
+- {0.0, "0"},
++ {0.0, "0.0"},
+ {1.25, "1.25"},
+- {1.33518e+012, "1.33518e+12"},
+- {1.33489e+012, "1.33489e+12"},
+- {1.33505e+012, "1.33505e+12"},
+- {1.33545e+009, "1335450000"},
+- {1.33503e+009, "1335030000"},
++ {1.33518e+012, "1335180000000.0"},
++ {1.33489e+012, "1334890000000.0"},
++ {1.33505e+012, "1335050000000.0"},
++ {1.33545e+009, "1335450000.0"},
++ {1.33503e+009, "1335030000.0"},
+ };
+
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+@@ -833,12 +822,12 @@ TEST(StringNumberConversionsTest, Double
+ const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
+ double input = 0;
+ memcpy(&input, input_bytes, arraysize(input_bytes));
+- EXPECT_EQ("1335179083776", DoubleToString(input));
++ EXPECT_EQ("1335179083776.0", DoubleToString(input));
+ const char input_bytes2[8] =
+ {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'};
+ input = 0;
+ memcpy(&input, input_bytes2, arraysize(input_bytes2));
+- EXPECT_EQ("1334890332160", DoubleToString(input));
++ EXPECT_EQ("1334890332160.0", DoubleToString(input));
+ }
+
+ TEST(StringNumberConversionsTest, HexEncode) {
diff --git a/libchrome_tools/patch/file_posix.patch b/libchrome_tools/patch/file_posix.patch
new file mode 100644
index 000000000..c7428e347
--- /dev/null
+++ b/libchrome_tools/patch/file_posix.patch
@@ -0,0 +1,15 @@
+# On Android, lseek64 should be used, whlie lseek should be in other platfrom.
+
+--- a/base/files/file_posix.cc
++++ b/base/files/file_posix.cc
+@@ -185,7 +185,9 @@ int64_t File::Seek(Whence whence, int64_
+
+ SCOPED_FILE_TRACE_WITH_SIZE("Seek", offset);
+
+-#if defined(OS_ANDROID)
++// Additionally check __BIONIC__ since older versions of Android don't define
++// _FILE_OFFSET_BITS.
++#if _FILE_OFFSET_BITS != 64 || defined(__BIONIC__)
+ static_assert(sizeof(int64_t) == sizeof(off64_t), "off64_t must be 64 bits");
+ return lseek64(file_.get(), static_cast<off64_t>(offset),
+ static_cast<int>(whence));
diff --git a/libchrome_tools/patch/gmock.patch b/libchrome_tools/patch/gmock.patch
new file mode 100644
index 000000000..a38afdce2
--- /dev/null
+++ b/libchrome_tools/patch/gmock.patch
@@ -0,0 +1,6 @@
+# Use system installed gmock library.
+
+--- /dev/null
++++ b/testing/gmock/include/gmock/gmock.h
+@@ -0,0 +1 @@
++#include <gmock/gmock.h>
diff --git a/libchrome_tools/patch/gtest.patch b/libchrome_tools/patch/gtest.patch
new file mode 100644
index 000000000..6da17c92e
--- /dev/null
+++ b/libchrome_tools/patch/gtest.patch
@@ -0,0 +1,10 @@
+# Use system installed gtest library.
+
+--- /dev/null
++++ b/testing/gtest/include/gtest/gtest.h
+@@ -0,0 +1 @@
++#include <gtest/gtest.h>
+--- /dev/null
++++ b/testing/gtest/include/gtest/gtest_prod.h
+@@ -0,0 +1 @@
++#include <gtest/gtest_prod.h>
diff --git a/libchrome_tools/patch/hash.patch b/libchrome_tools/patch/hash.patch
new file mode 100644
index 000000000..71e13d70e
--- /dev/null
+++ b/libchrome_tools/patch/hash.patch
@@ -0,0 +1,28 @@
+# libchrome does not support SuperFastHash. Instead use std::hash.
+
+--- a/base/hash.cc
++++ b/base/hash.cc
+@@ -4,19 +4,13 @@
+
+ #include "base/hash.h"
+
+-// Definition in base/third_party/superfasthash/superfasthash.c. (Third-party
+-// code did not come with its own header file, so declaring the function here.)
+-// Note: This algorithm is also in Blink under Source/wtf/StringHasher.h.
+-extern "C" uint32_t SuperFastHash(const char* data, int len);
++#include <functional>
+
+ namespace base {
+
+-uint32_t SuperFastHash(const char* data, size_t length) {
+- if (length > static_cast<size_t>(std::numeric_limits<int>::max())) {
+- NOTREACHED();
+- return 0;
+- }
+- return ::SuperFastHash(data, static_cast<int>(length));
++uint32_t SuperFastHash(const char* data, size_t len) {
++ std::hash<std::string> hash_fn;
++ return hash_fn(std::string(data, len));
+ }
+
+ } // namespace base
diff --git a/libchrome_tools/patch/lazy_instance.patch b/libchrome_tools/patch/lazy_instance.patch
new file mode 100644
index 000000000..d144137a6
--- /dev/null
+++ b/libchrome_tools/patch/lazy_instance.patch
@@ -0,0 +1,18 @@
+# LAZY_INSTANCE_INITIALIZER will be embedded into the users of libchrome,
+# and could cause compile warning.
+
+--- a/base/lazy_instance.h
++++ b/base/lazy_instance.h
+@@ -48,7 +48,11 @@
+ // initialization, as base's LINKER_INITIALIZED requires a constructor and on
+ // some compilers (notably gcc 4.4) this still ends up needing runtime
+ // initialization.
+-#define LAZY_INSTANCE_INITIALIZER {0}
++#ifdef __clang__
++ #define LAZY_INSTANCE_INITIALIZER {}
++#else
++ #define LAZY_INSTANCE_INITIALIZER {0, 0}
++#endif
+
+ namespace base {
+
diff --git a/libchrome_tools/patch/libevent.patch b/libchrome_tools/patch/libevent.patch
new file mode 100644
index 000000000..723d62165
--- /dev/null
+++ b/libchrome_tools/patch/libevent.patch
@@ -0,0 +1,13 @@
+--- /dev/null
++++ b/base/third_party/libevent/event.h
+@@ -0,0 +1,10 @@
++// The Chromium build contains its own checkout of libevent. This stub is used
++// when building the Chrome OS or Android libchrome package to instead use the
++// system headers.
++#if defined(__ANDROID__) || defined(__ANDROID_HOST__)
++#include <event2/event.h>
++#include <event2/event_compat.h>
++#include <event2/event_struct.h>
++#else
++#include <event.h>
++#endif
diff --git a/libchrome_tools/patch/logging.patch b/libchrome_tools/patch/logging.patch
new file mode 100644
index 000000000..8deece9b8
--- /dev/null
+++ b/libchrome_tools/patch/logging.patch
@@ -0,0 +1,80 @@
+--- a/base/logging.cc
++++ b/base/logging.cc
+@@ -71,7 +71,11 @@ typedef pthread_mutex_t* MutexHandle;
+ #include "base/posix/safe_strerror.h"
+ #endif
+
+-#if defined(OS_ANDROID)
++#if !defined(OS_ANDROID)
++#include "base/files/file_path.h"
++#endif
++
++#if defined(OS_ANDROID) || defined(__ANDROID__)
+ #include <android/log.h>
+ #endif
+
+@@ -358,21 +362,23 @@ bool BaseInitLoggingImpl(const LoggingSe
+ // Can log only to the system debug log.
+ CHECK_EQ(settings.logging_dest & ~LOG_TO_SYSTEM_DEBUG_LOG, 0);
+ #endif
+- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+- // Don't bother initializing |g_vlog_info| unless we use one of the
+- // vlog switches.
+- if (command_line->HasSwitch(switches::kV) ||
+- command_line->HasSwitch(switches::kVModule)) {
+- // NOTE: If |g_vlog_info| has already been initialized, it might be in use
+- // by another thread. Don't delete the old VLogInfo, just create a second
+- // one. We keep track of both to avoid memory leak warnings.
+- CHECK(!g_vlog_info_prev);
+- g_vlog_info_prev = g_vlog_info;
+-
+- g_vlog_info =
+- new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
+- command_line->GetSwitchValueASCII(switches::kVModule),
+- &g_min_log_level);
++ if (base::CommandLine::InitializedForCurrentProcess()) {
++ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
++ // Don't bother initializing |g_vlog_info| unless we use one of the
++ // vlog switches.
++ if (command_line->HasSwitch(switches::kV) ||
++ command_line->HasSwitch(switches::kVModule)) {
++ // NOTE: If |g_vlog_info| has already been initialized, it might be in use
++ // by another thread. Don't delete the old VLogInfo, just create a second
++ // one. We keep track of both to avoid memory leak warnings.
++ CHECK(!g_vlog_info_prev);
++ g_vlog_info_prev = g_vlog_info;
++
++ g_vlog_info =
++ new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
++ command_line->GetSwitchValueASCII(switches::kVModule),
++ &g_min_log_level);
++ }
+ }
+
+ g_logging_destination = settings.logging_dest;
+@@ -668,7 +674,7 @@ LogMessage::~LogMessage() {
+
+ asl_send(asl_client.get(), asl_message.get());
+ }
+-#elif defined(OS_ANDROID)
++#elif defined(OS_ANDROID) || defined(__ANDROID__)
+ android_LogPriority priority =
+ (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
+ switch (severity_) {
+@@ -685,7 +691,16 @@ LogMessage::~LogMessage() {
+ priority = ANDROID_LOG_FATAL;
+ break;
+ }
++#if defined(OS_ANDROID)
+ __android_log_write(priority, "chromium", str_newline.c_str());
++#else
++ __android_log_write(
++ priority,
++ base::CommandLine::InitializedForCurrentProcess() ?
++ base::CommandLine::ForCurrentProcess()->
++ GetProgram().BaseName().value().c_str() : nullptr,
++ str_newline.c_str());
++#endif // defined(OS_ANDROID)
+ #endif
+ ignore_result(fwrite(str_newline.data(), str_newline.size(), 1, stderr));
+ fflush(stderr);
diff --git a/libchrome_tools/patch/macros.patch b/libchrome_tools/patch/macros.patch
new file mode 100644
index 000000000..f57ec8867
--- /dev/null
+++ b/libchrome_tools/patch/macros.patch
@@ -0,0 +1,69 @@
+--- a/base/macros.h
++++ b/base/macros.h
+@@ -12,19 +12,32 @@
+
+ #include <stddef.h> // For size_t.
+
++#if defined(ANDROID)
++// Prefer Android's libbase definitions to our own.
++#include <android-base/macros.h>
++#endif // defined(ANDROID)
++
++// We define following macros conditionally as they may be defined by another libraries.
++
+ // Put this in the declarations for a class to be uncopyable.
++#if !defined(DISALLOW_COPY)
+ #define DISALLOW_COPY(TypeName) \
+ TypeName(const TypeName&) = delete
++#endif
+
+ // Put this in the declarations for a class to be unassignable.
++#if !defined(DISALLOW_ASSIGN)
+ #define DISALLOW_ASSIGN(TypeName) \
+ void operator=(const TypeName&) = delete
++#endif
+
+ // A macro to disallow the copy constructor and operator= functions.
+ // This should be used in the private: declarations for a class.
++#if !defined(DISALLOW_COPY_AND_ASSIGN)
+ #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete
++#endif
+
+ // A macro to disallow all the implicit constructors, namely the
+ // default constructor, copy constructor and operator= functions.
+@@ -32,9 +45,11 @@
+ // This should be used in the private: declarations for a class
+ // that wants to prevent anyone from instantiating it. This is
+ // especially useful for classes containing only static methods.
++#if !defined(DISALLOW_IMPLICIT_CONSTRUCTORS)
+ #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName() = delete; \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
++#endif
+
+ // The arraysize(arr) macro returns the # of elements in an array arr. The
+ // expression is a compile-time constant, and therefore can be used in defining
+@@ -45,8 +60,10 @@
+ // This template function declaration is used in defining arraysize.
+ // Note that the function doesn't need an implementation, as we only
+ // use its type.
++#if !defined(arraysize)
+ template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
+ #define arraysize(array) (sizeof(ArraySizeHelper(array)))
++#endif
+
+ // Used to explicitly mark the return value of a function as unused. If you are
+ // really sure you don't want to do anything with the return value of a function
+@@ -79,8 +96,10 @@ enum LinkerInitialized { LINKER_INITIALI
+ // Use these to declare and define a static local variable (static T;) so that
+ // it is leaked so that its destructors are not called at exit. If you need
+ // thread-safe initialization, use base/lazy_instance.h instead.
++#if !defined(CR_DEFINE_STATIC_LOCAL)
+ #define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \
+ static type& name = *new type arguments
++#endif
+
+ } // base
+
diff --git a/libchrome_tools/patch/message_loop.patch b/libchrome_tools/patch/message_loop.patch
new file mode 100644
index 000000000..0ab36300e
--- /dev/null
+++ b/libchrome_tools/patch/message_loop.patch
@@ -0,0 +1,13 @@
+--- a/base/message_loop/message_loop.h
++++ b/base/message_loop/message_loop.h
+@@ -565,7 +565,9 @@ class BASE_EXPORT MessageLoopForIO : pub
+ // Returns the MessageLoopForIO of the current thread.
+ static MessageLoopForIO* current() {
+ MessageLoop* loop = MessageLoop::current();
+- DCHECK(loop);
++ DCHECK(loop) << "Can't call MessageLoopForIO::current() when no message "
++ "loop was created for this thread. Use "
++ " MessageLoop::current() or MessageLoopForIO::IsCurrent().";
+ DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
+ return static_cast<MessageLoopForIO*>(loop);
+ }
diff --git a/libchrome_tools/patch/modp_b64.patch b/libchrome_tools/patch/modp_b64.patch
new file mode 100644
index 000000000..89d838c85
--- /dev/null
+++ b/libchrome_tools/patch/modp_b64.patch
@@ -0,0 +1,19 @@
+--- /dev/null
++++ b/third_party/modp_b64/modp_b64.h
+@@ -0,0 +1,16 @@
++// Copyright (C) 2018 The Android Open Source Project
++//
++// 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.
++
++// Redirect to system header.
++#include <modp_b64/modp_b64.h>
diff --git a/libchrome_tools/patch/path_service.patch b/libchrome_tools/patch/path_service.patch
new file mode 100644
index 000000000..f831d984e
--- /dev/null
+++ b/libchrome_tools/patch/path_service.patch
@@ -0,0 +1,92 @@
+# Currently, PathService is not available on libchrome.
+
+--- a/base/files/file_util_posix.cc
++++ b/base/files/file_util_posix.cc
+@@ -29,7 +29,6 @@
+ #include "base/logging.h"
+ #include "base/macros.h"
+ #include "base/memory/singleton.h"
+-#include "base/path_service.h"
+ #include "base/posix/eintr_wrapper.h"
+ #include "base/stl_util.h"
+ #include "base/strings/string_split.h"
+@@ -50,6 +49,7 @@
+ #if defined(OS_ANDROID)
+ #include "base/android/content_uri_utils.h"
+ #include "base/os_compat_android.h"
++#include "base/path_service.h"
+ #endif
+
+ #if !defined(OS_IOS)
+@@ -533,6 +533,8 @@ bool GetTempDir(FilePath* path) {
+ } else {
+ #if defined(OS_ANDROID)
+ return PathService::Get(base::DIR_CACHE, path);
++#elif defined(__ANDROID__)
++ *path = FilePath("/data/local/tmp");
+ #else
+ *path = FilePath("/tmp");
+ #endif
+--- a/base/json/json_reader_unittest.cc
++++ b/base/json/json_reader_unittest.cc
+@@ -8,11 +8,14 @@
+
+ #include <memory>
+
++#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+ #include "base/base_paths.h"
++#include "base/path_service.h"
++#endif
++
+ #include "base/files/file_util.h"
+ #include "base/logging.h"
+ #include "base/macros.h"
+-#include "base/path_service.h"
+ #include "base/strings/string_piece.h"
+ #include "base/strings/utf_string_conversions.h"
+ #include "base/values.h"
+@@ -567,6 +570,7 @@ TEST(JSONReaderTest, Reading) {
+ }
+ }
+
++#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+ TEST(JSONReaderTest, ReadFromFile) {
+ FilePath path;
+ ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &path));
+@@ -581,6 +585,7 @@ TEST(JSONReaderTest, ReadFromFile) {
+ ASSERT_TRUE(root) << reader.GetErrorMessage();
+ EXPECT_TRUE(root->IsType(Value::Type::DICTIONARY));
+ }
++#endif // !__ANDROID__ && !__ANDROID_HOST__
+
+ // Tests that the root of a JSON object can be deleted safely while its
+ // children outlive it.
+--- a/base/json/json_value_serializer_unittest.cc
++++ b/base/json/json_value_serializer_unittest.cc
+@@ -11,7 +11,9 @@
+ #include "base/json/json_reader.h"
+ #include "base/json/json_string_value_serializer.h"
+ #include "base/json/json_writer.h"
++#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+ #include "base/path_service.h"
++#endif
+ #include "base/strings/string_piece.h"
+ #include "base/strings/string_util.h"
+ #include "base/strings/utf_string_conversions.h"
+@@ -395,6 +397,8 @@ TEST(JSONValueSerializerTest, JSONReader
+ ASSERT_FALSE(JSONReader::Read("/ * * / [1]"));
+ }
+
++#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
++
+ class JSONFileValueSerializerTest : public testing::Test {
+ protected:
+ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
+@@ -481,6 +485,7 @@ TEST_F(JSONFileValueSerializerTest, NoWh
+ std::unique_ptr<Value> root = deserializer.Deserialize(nullptr, nullptr);
+ ASSERT_TRUE(root);
+ }
++#endif // !__ANDROID__ && !__ANDROID_HOST__
+
+ } // namespace
+
diff --git a/libchrome_tools/patch/protobuf.patch b/libchrome_tools/patch/protobuf.patch
new file mode 100644
index 000000000..343da9c45
--- /dev/null
+++ b/libchrome_tools/patch/protobuf.patch
@@ -0,0 +1,4 @@
+--- /dev/null
++++ b/third_party/protobuf/src/google/protobuf/message_lite.h
+@@ -0,0 +1 @@
++#include <google/protobuf/message_lite.h>
diff --git a/libchrome_tools/patch/shared_memory_posix.patch b/libchrome_tools/patch/shared_memory_posix.patch
new file mode 100644
index 000000000..abae9f455
--- /dev/null
+++ b/libchrome_tools/patch/shared_memory_posix.patch
@@ -0,0 +1,56 @@
+--- a/base/memory/shared_memory_posix.cc
++++ b/base/memory/shared_memory_posix.cc
+@@ -27,6 +27,8 @@
+
+ #if defined(OS_ANDROID)
+ #include "base/os_compat_android.h"
++#endif
++#if defined(OS_ANDROID) || defined(__ANDROID__)
+ #include "third_party/ashmem/ashmem.h"
+ #endif
+
+@@ -96,7 +98,7 @@ bool SharedMemory::CreateAndMapAnonymous
+ return CreateAnonymous(size) && Map(size);
+ }
+
+-#if !defined(OS_ANDROID)
++#if !defined(OS_ANDROID) && !defined(__ANDROID__)
+ // static
+ bool SharedMemory::GetSizeFromSharedMemoryHandle(
+ const SharedMemoryHandle& handle,
+@@ -255,7 +257,7 @@ bool SharedMemory::Open(const std::strin
+ return PrepareMapFile(std::move(fp), std::move(readonly_fd), &mapped_file_,
+ &readonly_mapped_file_);
+ }
+-#endif // !defined(OS_ANDROID)
++#endif // !defined(OS_ANDROID) && !defined(__ANDROID__)
+
+ bool SharedMemory::MapAt(off_t offset, size_t bytes) {
+ if (mapped_file_ == -1)
+@@ -267,7 +269,7 @@ bool SharedMemory::MapAt(off_t offset, s
+ if (memory_)
+ return false;
+
+-#if defined(OS_ANDROID)
++#if defined(OS_ANDROID) || defined(__ANDROID__)
+ // On Android, Map can be called with a size and offset of zero to use the
+ // ashmem-determined size.
+ if (bytes == 0) {
+@@ -332,7 +334,7 @@ void SharedMemory::Close() {
+ }
+ }
+
+-#if !defined(OS_ANDROID)
++#if !defined(OS_ANDROID) && !defined(__ANDROID__)
+ // For the given shmem named |mem_name|, return a filename to mmap()
+ // (and possibly create). Modifies |filename|. Return false on
+ // error, or true of we are happy.
+@@ -355,7 +357,7 @@ bool SharedMemory::FilePathForMemoryName
+ *path = temp_dir.AppendASCII(name_base + ".shmem." + mem_name);
+ return true;
+ }
+-#endif // !defined(OS_ANDROID)
++#endif // !defined(OS_ANDROID) && !defined(__ANDROID__)
+
+ bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
+ SharedMemoryHandle* new_handle,
diff --git a/libchrome_tools/patch/ssl.patch b/libchrome_tools/patch/ssl.patch
new file mode 100644
index 000000000..f4a2f8f83
--- /dev/null
+++ b/libchrome_tools/patch/ssl.patch
@@ -0,0 +1,126 @@
+# Chrome asumes boringssl, while system installed ssl library may not.
+
+--- a/crypto/openssl_util.cc
++++ b/crypto/openssl_util.cc
+@@ -4,6 +4,13 @@
+
+ #include "crypto/openssl_util.h"
+
++#if defined(OPENSSL_IS_BORINGSSL)
++#include <openssl/cpu.h>
++#else
++#include <openssl/ssl.h>
++#endif
++#include <openssl/crypto.h>
++#include <openssl/err.h>
+ #include <stddef.h>
+ #include <stdint.h>
+
+@@ -11,8 +18,6 @@
+
+ #include "base/logging.h"
+ #include "base/strings/string_piece.h"
+-#include "third_party/boringssl/src/include/openssl/crypto.h"
+-#include "third_party/boringssl/src/include/openssl/err.h"
+
+ namespace crypto {
+
+@@ -35,8 +40,12 @@ int OpenSSLErrorCallback(const char* str
+ } // namespace
+
+ void EnsureOpenSSLInit() {
++#if defined(OPENSSL_IS_BORINGSSL)
+ // CRYPTO_library_init may be safely called concurrently.
+ CRYPTO_library_init();
++#else
++ SSL_library_init();
++#endif
+ }
+
+ void ClearOpenSSLERRStack(const tracked_objects::Location& location) {
+--- a/crypto/rsa_private_key.h
++++ b/crypto/rsa_private_key.h
+@@ -7,6 +7,7 @@
+
+ #include <stddef.h>
+ #include <stdint.h>
++#include <openssl/base.h>
+
+ #include <memory>
+ #include <vector>
+@@ -14,7 +15,6 @@
+ #include "base/macros.h"
+ #include "build/build_config.h"
+ #include "crypto/crypto_export.h"
+-#include "third_party/boringssl/src/include/openssl/base.h"
+
+ namespace crypto {
+
+--- a/crypto/secure_hash.cc
++++ b/crypto/secure_hash.cc
+@@ -4,14 +4,18 @@
+
+ #include "crypto/secure_hash.h"
+
++#if defined(OPENSSL_IS_BORINGSSL)
++#include <openssl/mem.h>
++#else
++#include <openssl/crypto.h>
++#endif
++#include <openssl/sha.h>
+ #include <stddef.h>
+
+ #include "base/logging.h"
+ #include "base/memory/ptr_util.h"
+ #include "base/pickle.h"
+ #include "crypto/openssl_util.h"
+-#include "third_party/boringssl/src/include/openssl/mem.h"
+-#include "third_party/boringssl/src/include/openssl/sha.h"
+
+ namespace crypto {
+
+--- a/crypto/signature_verifier.h
++++ b/crypto/signature_verifier.h
+@@ -54,9 +54,9 @@ class CRYPTO_EXPORT SignatureVerifier {
+ // subjectPublicKey BIT STRING }
+ bool VerifyInit(SignatureAlgorithm signature_algorithm,
+ const uint8_t* signature,
+- size_t signature_len,
++ int signature_len,
+ const uint8_t* public_key_info,
+- size_t public_key_info_len);
++ int public_key_info_len);
+
+ // Initiates a RSA-PSS signature verification operation. This should be
+ // followed by one or more VerifyUpdate calls and a VerifyFinal call.
+@@ -76,14 +76,14 @@ class CRYPTO_EXPORT SignatureVerifier {
+ // subjectPublicKey BIT STRING }
+ bool VerifyInitRSAPSS(HashAlgorithm hash_alg,
+ HashAlgorithm mask_hash_alg,
+- size_t salt_len,
++ int salt_len,
+ const uint8_t* signature,
+- size_t signature_len,
++ int signature_len,
+ const uint8_t* public_key_info,
+- size_t public_key_info_len);
++ int public_key_info_len);
+
+ // Feeds a piece of the data to the signature verifier.
+- void VerifyUpdate(const uint8_t* data_part, size_t data_part_len);
++ void VerifyUpdate(const uint8_t* data_part, int data_part_len);
+
+ // Concludes a signature verification operation. Returns true if the
+ // signature is valid. Returns false if the signature is invalid or an
+@@ -94,9 +94,9 @@ class CRYPTO_EXPORT SignatureVerifier {
+ bool CommonInit(int pkey_type,
+ const EVP_MD* digest,
+ const uint8_t* signature,
+- size_t signature_len,
++ int signature_len,
+ const uint8_t* public_key_info,
+- size_t public_key_info_len,
++ int public_key_info_len,
+ EVP_PKEY_CTX** pkey_ctx);
+
+ void Reset();
diff --git a/libchrome_tools/patch/stack_trace_posix.patch b/libchrome_tools/patch/stack_trace_posix.patch
new file mode 100644
index 000000000..3e2c18818
--- /dev/null
+++ b/libchrome_tools/patch/stack_trace_posix.patch
@@ -0,0 +1,45 @@
+# stack_trace_posix.cc depends on glibc, but Android uses bionic.
+# Exclude glibc specific part.
+
+--- a/base/debug/stack_trace_posix.cc
++++ b/base/debug/stack_trace_posix.cc
+@@ -59,7 +59,7 @@ namespace {
+
+ volatile sig_atomic_t in_signal_handler = 0;
+
+-#if !defined(USE_SYMBOLIZE)
++#if !defined(USE_SYMBOLIZE) && defined(__GLIBCXX__)
+ // The prefix used for mangled symbols, per the Itanium C++ ABI:
+ // http://www.codesourcery.com/cxx-abi/abi.html#mangling
+ const char kMangledSymbolPrefix[] = "_Z";
+@@ -68,9 +68,9 @@ const char kMangledSymbolPrefix[] = "_Z"
+ // (('a'..'z').to_a+('A'..'Z').to_a+('0'..'9').to_a + ['_']).join
+ const char kSymbolCharacters[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+-#endif // !defined(USE_SYMBOLIZE)
++#endif // !defined(USE_SYMBOLIZE) && defined(__GLIBCXX__)
+
+-#if !defined(USE_SYMBOLIZE)
++#if !defined(USE_SYMBOLIZE) && !defined(__UCLIBC__)
+ // Demangles C++ symbols in the given text. Example:
+ //
+ // "out/Debug/base_unittests(_ZN10StackTraceC1Ev+0x20) [0x817778c]"
+@@ -79,8 +79,7 @@ const char kSymbolCharacters[] =
+ void DemangleSymbols(std::string* text) {
+ // Note: code in this function is NOT async-signal safe (std::string uses
+ // malloc internally).
+-
+-#if !defined(__UCLIBC__)
++#if defined(__GLIBCXX__) && !defined(__UCLIBC__)
+
+ std::string::size_type search_from = 0;
+ while (search_from < text->size()) {
+@@ -116,7 +115,7 @@ void DemangleSymbols(std::string* text)
+ search_from = mangled_start + 2;
+ }
+ }
+-#endif // !defined(__UCLIBC__)
++#endif // defined(__GLIBCXX__) && !defined(__UCLIBC__)
+ }
+ #endif // !defined(USE_SYMBOLIZE)
+
diff --git a/libchrome_tools/patch/statfs_f_type.patch b/libchrome_tools/patch/statfs_f_type.patch
new file mode 100644
index 000000000..989380b5d
--- /dev/null
+++ b/libchrome_tools/patch/statfs_f_type.patch
@@ -0,0 +1,40 @@
+# In some platforms, |statfs_buf.f_type| is declared as signed, but some of the
+# values will overflow it, causing narrowing warnings. Cast to the largest
+# possible unsigned integer type to avoid it.
+
+--- a/base/files/file_util_linux.cc
++++ b/base/files/file_util_linux.cc
+@@ -6,6 +6,7 @@
+
+ #include <errno.h>
+ #include <linux/magic.h>
++#include <stdint.h>
+ #include <sys/vfs.h>
+
+ #include "base/files/file_path.h"
+@@ -23,7 +24,10 @@ bool GetFileSystemType(const FilePath& p
+
+ // Not all possible |statfs_buf.f_type| values are in linux/magic.h.
+ // Missing values are copied from the statfs man page.
+- switch (statfs_buf.f_type) {
++ // In some platforms, |statfs_buf.f_type| is declared as signed, but some of
++ // the values will overflow it, causing narrowing warnings. Cast to the
++ // largest possible unsigned integer type to avoid it.
++ switch (static_cast<uintmax_t>(statfs_buf.f_type)) {
+ case 0:
+ *type = FILE_SYSTEM_0;
+ break;
+--- a/base/sys_info_posix.cc
++++ b/base/sys_info_posix.cc
+@@ -85,7 +85,10 @@ bool IsStatsZeroIfUnlimited(const base::
+ if (HANDLE_EINTR(statfs(path.value().c_str(), &stats)) != 0)
+ return false;
+
+- switch (stats.f_type) {
++ // In some platforms, |statfs_buf.f_type| is declared as signed, but some of
++ // the values will overflow it, causing narrowing warnings. Cast to the
++ // largest possible unsigned integer type to avoid it.
++ switch (static_cast<uintmax_t>(stats.f_type)) {
+ case TMPFS_MAGIC:
+ case HUGETLBFS_MAGIC:
+ case RAMFS_MAGIC:
diff --git a/libchrome_tools/patch/subprocess.patch b/libchrome_tools/patch/subprocess.patch
new file mode 100644
index 000000000..ad4457d2d
--- /dev/null
+++ b/libchrome_tools/patch/subprocess.patch
@@ -0,0 +1,74 @@
+--- a/base/process/process_metrics_unittest.cc
++++ b/base/process/process_metrics_unittest.cc
+@@ -549,6 +549,9 @@ MULTIPROCESS_TEST_MAIN(ChildMain) {
+
+ } // namespace
+
++// Arc++ note: don't compile as SpawnMultiProcessTestChild brings in a lot of
++// extra dependency.
++#if !defined(OS_ANDROID) && !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+ TEST(ProcessMetricsTest, GetOpenFdCount) {
+ ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+@@ -562,9 +565,23 @@ TEST(ProcessMetricsTest, GetOpenFdCount)
+
+ std::unique_ptr<ProcessMetrics> metrics(
+ ProcessMetrics::CreateProcessMetrics(spawn_child.process.Handle()));
+- EXPECT_EQ(0, metrics->GetOpenFdCount());
++ // Try a couple times to observe the child with 0 fds open.
++ // Sometimes we've seen that the child can have 1 remaining
++ // fd shortly after receiving the signal. Potentially this
++ // is actually the signal file still open in the child.
++ int open_fds = -1;
++ for (int tries = 0; tries < 5; ++tries) {
++ open_fds = metrics->GetOpenFdCount();
++ if (!open_fds) {
++ break;
++ }
++ PlatformThread::Sleep(TimeDelta::FromMilliseconds(1));
++ }
++ EXPECT_EQ(0, open_fds);
+ ASSERT_TRUE(spawn_child.process.Terminate(0, true));
+ }
++#endif // !defined(__ANDROID__)
++
+ #endif // defined(OS_LINUX)
+
+ } // namespace debug
+--- a/base/test/multiprocess_test.cc
++++ b/base/test/multiprocess_test.cc
+@@ -12,7 +12,7 @@
+
+ namespace base {
+
+-#if !defined(OS_ANDROID)
++#if !defined(OS_ANDROID) && !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+ SpawnChildResult SpawnMultiProcessTestChild(
+ const std::string& procname,
+ const CommandLine& base_command_line,
+@@ -41,7 +41,7 @@ bool TerminateMultiProcessTestChild(cons
+ return process.Terminate(exit_code, wait);
+ }
+
+-#endif // !defined(OS_ANDROID)
++#endif // !OS_ANDROID && !__ANDROID__ && !__ANDROID_HOST__
+
+ CommandLine GetMultiProcessTestChildBaseCommandLine() {
+ CommandLine cmd_line = *CommandLine::ForCurrentProcess();
+@@ -54,6 +54,8 @@ CommandLine GetMultiProcessTestChildBase
+ MultiProcessTest::MultiProcessTest() {
+ }
+
++// Don't compile on Arc++.
++#if 0
+ SpawnChildResult MultiProcessTest::SpawnChild(const std::string& procname) {
+ LaunchOptions options;
+ #if defined(OS_WIN)
+@@ -67,6 +69,7 @@ SpawnChildResult MultiProcessTest::Spawn
+ const LaunchOptions& options) {
+ return SpawnMultiProcessTestChild(procname, MakeCmdLine(procname), options);
+ }
++#endif
+
+ CommandLine MultiProcessTest::MakeCmdLine(const std::string& procname) {
+ CommandLine command_line = GetMultiProcessTestChildBaseCommandLine();
diff --git a/libchrome_tools/patch/symbolize.patch b/libchrome_tools/patch/symbolize.patch
new file mode 100644
index 000000000..a7eeda516
--- /dev/null
+++ b/libchrome_tools/patch/symbolize.patch
@@ -0,0 +1,18 @@
+--- /dev/null
++++ b/base/third_party/symbolize/symbolize.h
+@@ -0,0 +1,15 @@
++// Copyright (C) 2018 The Android Open Source Project
++//
++// 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.
++
++#error "symbolize support was removed from libchrome"
diff --git a/libchrome_tools/patch/task_scheduler.patch b/libchrome_tools/patch/task_scheduler.patch
new file mode 100644
index 000000000..c32520ba4
--- /dev/null
+++ b/libchrome_tools/patch/task_scheduler.patch
@@ -0,0 +1,152 @@
+# libchrome does not support TaskScheduler.
+
+--- a/base/threading/sequenced_worker_pool.cc
++++ b/base/threading/sequenced_worker_pool.cc
+@@ -27,8 +27,12 @@
+ #include "base/strings/stringprintf.h"
+ #include "base/synchronization/condition_variable.h"
+ #include "base/synchronization/lock.h"
++// Don't enable the redirect to TaskScheduler on Arc++ to avoid pulling a bunch
++// of dependencies. Some code also #ifdef'ed below.
++#if 0
+ #include "base/task_scheduler/post_task.h"
+ #include "base/task_scheduler/task_scheduler.h"
++#endif
+ #include "base/threading/platform_thread.h"
+ #include "base/threading/sequenced_task_runner_handle.h"
+ #include "base/threading/simple_thread.h"
+@@ -755,10 +759,13 @@ bool SequencedWorkerPool::Inner::PostTas
+ if (optional_token_name)
+ sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name);
+
++ // See on top of the file why we don't compile this on Arc++.
++#if 0
+ if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
+ if (!PostTaskToTaskScheduler(std::move(sequenced), delay))
+ return false;
+ } else {
++#endif
+ SequencedWorkerPool::WorkerShutdown shutdown_behavior =
+ sequenced.shutdown_behavior;
+ pending_tasks_.insert(std::move(sequenced));
+@@ -767,7 +774,9 @@ bool SequencedWorkerPool::Inner::PostTas
+ blocking_shutdown_pending_task_count_++;
+
+ create_thread_id = PrepareToStartAdditionalThreadIfHelpful();
++#if 0
+ }
++#endif
+ }
+
+ // Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure
+@@ -802,6 +811,10 @@ bool SequencedWorkerPool::Inner::PostTas
+ bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler(
+ SequencedTask sequenced,
+ const TimeDelta& delay) {
++#if 1
++ NOTREACHED();
++ return false;
++#else
+ DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state);
+
+ lock_.AssertAcquired();
+@@ -832,12 +845,17 @@ bool SequencedWorkerPool::Inner::PostTas
+ return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits)
+ ->PostDelayedTask(sequenced.posted_from, std::move(sequenced.task),
+ delay);
++#endif
+ }
+
+ scoped_refptr<TaskRunner>
+ SequencedWorkerPool::Inner::GetTaskSchedulerTaskRunner(
+ int sequence_token_id,
+ const TaskTraits& traits) {
++#if 1
++ NOTREACHED();
++ return scoped_refptr<TaskRunner>();
++#else
+ DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state);
+
+ lock_.AssertAcquired();
+@@ -871,16 +889,19 @@ SequencedWorkerPool::Inner::GetTaskSched
+ }
+
+ return task_runner;
++#endif
+ }
+
+ bool SequencedWorkerPool::Inner::RunsTasksOnCurrentThread() const {
+ AutoLock lock(lock_);
+ if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
++#if 0
+ if (!runs_tasks_on_verifier_) {
+ runs_tasks_on_verifier_ = CreateTaskRunnerWithTraits(
+ TaskTraits().MayBlock().WithBaseSyncPrimitives().WithPriority(
+ task_priority_));
+ }
++#endif
+ return runs_tasks_on_verifier_->RunsTasksOnCurrentThread();
+ } else {
+ return ContainsKey(threads_, PlatformThread::CurrentId());
+@@ -1467,6 +1488,9 @@ void SequencedWorkerPool::EnableForProce
+ // static
+ void SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess(
+ TaskPriority max_task_priority) {
++#if 1
++ NOTREACHED();
++#else
+ // TODO(fdoray): Uncomment this line. It is initially commented to avoid a
+ // revert of the CL that adds debug::DumpWithoutCrashing() in case of
+ // waterfall failures.
+@@ -1474,6 +1498,7 @@ void SequencedWorkerPool::EnableWithRedi
+ DCHECK(TaskScheduler::GetInstance());
+ g_all_pools_state = AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER;
+ g_max_task_priority = max_task_priority;
++#endif
+ }
+
+ // static
+@@ -1623,8 +1648,12 @@ void SequencedWorkerPool::FlushForTestin
+ DCHECK(!RunsTasksOnCurrentThread());
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
++#if 1
++ NOTREACHED();
++#else
+ // TODO(gab): Remove this if http://crbug.com/622400 fails.
+ TaskScheduler::GetInstance()->FlushForTesting();
++#endif
+ } else {
+ inner_->CleanupForTesting();
+ }
+--- a/base/trace_event/trace_log.cc
++++ b/base/trace_event/trace_log.cc
+@@ -27,7 +27,10 @@
+ #include "base/strings/string_tokenizer.h"
+ #include "base/strings/stringprintf.h"
+ #include "base/sys_info.h"
++// post_task.h pulls in a lot of code not needed on Arc++.
++#if 0
+ #include "base/task_scheduler/post_task.h"
++#endif
+ #include "base/threading/platform_thread.h"
+ #include "base/threading/thread_id_name_manager.h"
+ #include "base/threading/thread_task_runner_handle.h"
+@@ -968,6 +971,7 @@ void TraceLog::FinishFlush(int generatio
+ }
+
+ if (use_worker_thread_) {
++#if 0
+ base::PostTaskWithTraits(
+ FROM_HERE, base::TaskTraits()
+ .MayBlock()
+@@ -978,6 +982,9 @@ void TraceLog::FinishFlush(int generatio
+ Passed(&previous_logged_events), flush_output_callback,
+ argument_filter_predicate));
+ return;
++#else
++ NOTREACHED();
++#endif
+ }
+
+ ConvertTraceEventsToTraceFormat(std::move(previous_logged_events),
diff --git a/libchrome_tools/patch/time.patch b/libchrome_tools/patch/time.patch
new file mode 100644
index 000000000..496e68f30
--- /dev/null
+++ b/libchrome_tools/patch/time.patch
@@ -0,0 +1,19 @@
+# Cherry-pick from r488841.
+
+--- a/base/time/time.h
++++ b/base/time/time.h
+@@ -341,6 +341,14 @@ class TimeBase {
+ // provided operators.
+ int64_t ToInternalValue() const { return us_; }
+
++ // The amount of time since the origin (or "zero") point. This is a syntactic
++ // convenience to aid in code readability, mainly for debugging/testing use
++ // cases.
++ //
++ // Warning: While the Time subclass has a fixed origin point, the origin for
++ // the other subclasses can vary each time the application is restarted.
++ TimeDelta since_origin() const { return TimeDelta::FromMicroseconds(us_); }
++
+ TimeClass& operator=(TimeClass other) {
+ us_ = other.us_;
+ return *(static_cast<TimeClass*>(this));
diff --git a/libchrome_tools/patch/valgrind.patch b/libchrome_tools/patch/valgrind.patch
new file mode 100644
index 000000000..7a7722c3a
--- /dev/null
+++ b/libchrome_tools/patch/valgrind.patch
@@ -0,0 +1,33 @@
+# On Android, use system valgrind, instead of ones checked in to the Chromium
+# repository.
+
+--- a/base/third_party/valgrind/memcheck.h
++++ b/base/third_party/valgrind/memcheck.h
+@@ -1,4 +1,6 @@
+-
++#ifdef ANDROID
++ #include "memcheck/memcheck.h"
++#else
+ /*
+ ----------------------------------------------------------------
+
+@@ -277,3 +279,4 @@ typedef
+
+ #endif
+
++#endif
+--- a/base/third_party/valgrind/valgrind.h
++++ b/base/third_party/valgrind/valgrind.h
+@@ -1,3 +1,6 @@
++#ifdef ANDROID
++ #include "include/valgrind.h"
++#else
+ /* -*- c -*-
+ ----------------------------------------------------------------
+
+@@ -4790,3 +4793,5 @@ VALGRIND_PRINTF_BACKTRACE(const char *fo
+ #undef PLAT_ppc64_aix5
+
+ #endif /* __VALGRIND_H */
++
++#endif
diff --git a/libchrome_tools/patch/virtual_destructor.patch b/libchrome_tools/patch/virtual_destructor.patch
new file mode 100644
index 000000000..64111333e
--- /dev/null
+++ b/libchrome_tools/patch/virtual_destructor.patch
@@ -0,0 +1,78 @@
+--- a/base/metrics/histogram.cc
++++ b/base/metrics/histogram.cc
+@@ -94,6 +94,7 @@ class Histogram::Factory {
+ uint32_t bucket_count,
+ int32_t flags)
+ : Factory(name, HISTOGRAM, minimum, maximum, bucket_count, flags) {}
++ virtual ~Factory() = default;
+
+ // Create histogram based on construction parameters. Caller takes
+ // ownership of the returned object.
+@@ -741,6 +742,7 @@ class LinearHistogram::Factory : public
+ bucket_count, flags) {
+ descriptions_ = descriptions;
+ }
++ ~Factory() override = default;
+
+ protected:
+ BucketRanges* CreateRanges() override {
+@@ -932,6 +934,7 @@ class BooleanHistogram::Factory : public
+ public:
+ Factory(const std::string& name, int32_t flags)
+ : Histogram::Factory(name, BOOLEAN_HISTOGRAM, 1, 2, 3, flags) {}
++ ~Factory() override = default;
+
+ protected:
+ BucketRanges* CreateRanges() override {
+@@ -1020,6 +1023,7 @@ class CustomHistogram::Factory : public
+ : Histogram::Factory(name, CUSTOM_HISTOGRAM, 0, 0, 0, flags) {
+ custom_ranges_ = custom_ranges;
+ }
++ ~Factory() override = default;
+
+ protected:
+ BucketRanges* CreateRanges() override {
+--- a/base/metrics/statistics_recorder.h
++++ b/base/metrics/statistics_recorder.h
+@@ -67,6 +67,7 @@ class BASE_EXPORT StatisticsRecorder {
+ // histograms from providers when necessary.
+ class HistogramProvider {
+ public:
++ virtual ~HistogramProvider() {}
+ // Merges all histogram information into the global versions.
+ virtual void MergeHistogramDeltas() = 0;
+ };
+--- a/base/bind_unittest.cc
++++ b/base/bind_unittest.cc
+@@ -69,6 +69,7 @@ static const int kChildValue = 2;
+
+ class Parent {
+ public:
++ virtual ~Parent() {}
+ void AddRef() const {}
+ void Release() const {}
+ virtual void VirtualSet() { value = kParentValue; }
+@@ -78,18 +79,23 @@ class Parent {
+
+ class Child : public Parent {
+ public:
++ ~Child() override {}
+ void VirtualSet() override { value = kChildValue; }
+ void NonVirtualSet() { value = kChildValue; }
+ };
+
+ class NoRefParent {
+ public:
++ virtual ~NoRefParent() {}
+ virtual void VirtualSet() { value = kParentValue; }
+ void NonVirtualSet() { value = kParentValue; }
+ int value;
+ };
+
+ class NoRefChild : public NoRefParent {
++ public:
++ ~NoRefChild() override {}
++ private:
+ void VirtualSet() override { value = kChildValue; }
+ void NonVirtualSet() { value = kChildValue; }
+ };
diff --git a/libchrome_tools/update_libchrome.py b/libchrome_tools/update_libchrome.py
new file mode 100644
index 000000000..89d97c26b
--- /dev/null
+++ b/libchrome_tools/update_libchrome.py
@@ -0,0 +1,158 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2018 The Android Open Source Project
+#
+# 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.
+
+"""Updates libchrome.
+
+This script uprevs the libchrome library with newer Chromium code.
+How to use:
+
+Prepare your local Chromium repository with the target revision.
+$ cd external/libchrome
+$ python3 libchrome_tools/update_libchrome.py \
+ --chromium_root=${PATH_TO_YOUR_LOCAL_CHROMIUM_REPO}
+
+This script does following things;
+- Clean existing libchrome code, except some manually created files and tools.
+- Copy necessary files from original Chromium repository.
+- Apply patches to the copied files, if necessary.
+"""
+
+
+import argparse
+import fnmatch
+import glob
+import os
+import re
+import shutil
+import subprocess
+
+
+_TOOLS_DIR = os.path.dirname(os.path.realpath(__file__))
+_LIBCHROME_ROOT = os.path.dirname(_TOOLS_DIR)
+
+
+# Files which are in the repository, but should not be imported from Chrome
+# repository.
+_IMPORT_BLACKLIST = [
+ # Libchrome specific files.
+ 'Android.bp',
+ 'MODULE_LICENSE_BSD',
+ 'NOTICE',
+ 'OWNERS',
+ 'SConstruct',
+ 'testrunner.cc',
+
+ # libchrome_tools is out of the update target.
+ 'libchrome_tools/*',
+
+ # Those files should be generated. Please see also buildflag_header.patch.
+ 'base/allocator/features.h',
+ 'base/debug/debugging_flags.h',
+
+ # Blacklist several third party libraries, instead system libraries should
+ # be used.
+ 'base/third_party/libevent/*',
+ 'base/third_party/symbolize/*',
+ 'testing/gmock/*',
+ 'testing/gtest/*',
+ 'third_party/*',
+]
+
+def _find_target_files():
+ """Returns target files to be upreved."""
+ output = subprocess.check_output(
+ ['git', 'ls-tree', '-r', '--name-only', '--full-name', 'HEAD'],
+ cwd=_LIBCHROME_ROOT).decode('utf-8')
+ exclude_pattern = re.compile('|'.join(
+ '(?:%s)' % fnmatch.translate(pattern) for pattern in _IMPORT_BLACKLIST))
+ return [filepath for filepath in output.splitlines()
+ if not exclude_pattern.match(filepath)]
+
+
+def _clean_existing_dir(output_root):
+ """Removes existing libchrome files.
+
+ Args:
+ output_root: Path to the output directory.
+ """
+ os.makedirs(output_root, mode=0o755, exist_ok=True)
+ for path in os.listdir(output_root):
+ target_path = os.path.join(output_root, path)
+ if not os.path.isdir(target_path) or path in ('.git', 'libchrome_tools'):
+ continue
+ shutil.rmtree(target_path)
+
+
+def _import_files(chromium_root, output_root):
+ """Copies files from Chromium repository into libchrome.
+
+ Args:
+ chromium_root: Path to the Chromium's repository.
+ output_root: Path to the output directory.
+ """
+ for filepath in _find_target_files():
+ target_path = os.path.join(output_root, filepath)
+ os.makedirs(os.path.dirname(target_path), mode=0o755, exist_ok=True)
+ shutil.copy2(os.path.join(chromium_root, filepath), target_path)
+
+
+def _apply_patch_files(patch_root, output_root):
+ """Applies patches.
+
+ libchrome needs some modification from Chromium repository, e.g. supporting
+ toolchain which is not used by Chrome, or using system library rather than
+ the library checked in the Chromium repository.
+ See each *.patch file in libchrome_tools/patch/ directory for details.
+
+ Args:
+ patch_root: Path to the directory containing patch files.
+ output_root: Path to the output directory.
+ """
+ for patch_file in glob.iglob(os.path.join(patch_root, '*.patch')):
+ with open(patch_file, 'r') as f:
+ subprocess.check_call(['patch', '-p1'], stdin=f, cwd=output_root)
+
+
+def _parse_args():
+ """Parses commandline arguments."""
+ parser = argparse.ArgumentParser()
+
+ # TODO(hidehiko): Support to specify the Chromium's revision number.
+ parser.add_argument(
+ '--chromium_root',
+ help='Root directory to the local chromium repository.')
+ parser.add_argument(
+ '--output_root',
+ default=_LIBCHROME_ROOT,
+ help='Output directory, which is libchrome root directory.')
+ parser.add_argument(
+ '--patch_dir',
+ default=os.path.join(_TOOLS_DIR, 'patch'),
+ help='Directory containing patch files to be applied.')
+
+ return parser.parse_args()
+
+
+def main():
+ args = _parse_args()
+ _clean_existing_dir(args.output_root)
+ _import_files(args.chromium_root, args.output_root)
+ _apply_patch_files(args.patch_dir, args.output_root)
+ # TODO(hidehiko): Create a git commit with filling templated message.
+
+
+if __name__ == '__main__':
+ main()