Import chromium-87.0.4280.66

This commit is contained in:
importer 2020-11-18 23:28:07 +08:00 committed by klzgrad
commit 71714cfdce
28757 changed files with 5774215 additions and 0 deletions

39
src/.clang-format Normal file
View File

@ -0,0 +1,39 @@
# Defines the Chromium style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium
# This defaults to 'Auto'. Explicitly set it for a while, so that
# 'vector<vector<int> >' in existing files gets formatted to
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
# 'int>>' if the file already contains at least one such instance.)
Standard: Cpp11
# Make sure code like:
# IPC_BEGIN_MESSAGE_MAP()
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
# IPC_END_MESSAGE_MAP()
# gets correctly indented.
MacroBlockBegin: "^\
BEGIN_MSG_MAP|\
BEGIN_MSG_MAP_EX|\
BEGIN_SAFE_MSG_MAP_EX|\
CR_BEGIN_MSG_MAP_EX|\
IPC_BEGIN_MESSAGE_MAP|\
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
IPC_STRUCT_BEGIN|\
IPC_STRUCT_BEGIN_WITH_PARENT|\
IPC_STRUCT_TRAITS_BEGIN|\
POLPARAMS_BEGIN|\
PPAPI_BEGIN_MESSAGE_MAP$"
MacroBlockEnd: "^\
CR_END_MSG_MAP|\
END_MSG_MAP|\
IPC_END_MESSAGE_MAP|\
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
IPC_STRUCT_END|\
IPC_STRUCT_TRAITS_END|\
POLPARAMS_END|\
PPAPI_END_MESSAGE_MAP$"
# TODO: Remove this once clang-format r357700 is rolled in.
JavaImportGroups: ['android', 'androidx', 'com', 'dalvik', 'junit', 'org', 'com.google.android.apps.chrome', 'org.chromium', 'java', 'javax']

55
src/.gitattributes vendored Normal file
View File

@ -0,0 +1,55 @@
# Stop Windows python license check presubmit errors by forcing LF checkout.
*.py text eol=lf
# Force LF checkout of the pins files to avoid transport_security_state_generator errors.
/net/http/*.pins text eol=lf
# Force LF checkout for all source files
*.bin binary
*.c text eol=lf
*.cc text eol=lf
*.cpp text eol=lf
*.csv text eol=lf
*.grd text eol=lf
*.grdp text eol=lf
*.gn text eol=lf
*.gni text eol=lf
*.h text eol=lf
*.html text eol=lf
*.idl text eol=lf
*.in text eol=lf
*.inc text eol=lf
*.java text eol=lf
*.js text eol=lf
*.json text eol=lf
*.json5 text eol=lf
*.md text eol=lf
*.mm text eol=lf
*.mojom text eol=lf
*.pdf -diff
*.proto text eol=lf
*.sh text eol=lf
*.sql text eol=lf
*.txt text eol=lf
*.xml text eol=lf
*.xslt text eol=lf
.clang-format text eol=lf
.eslintrc.js text eol=lf
.git-blame-ignore-revs text eol=lf
.gitattributes text eol=lf
.gitignore text eol=lf
.vpython text eol=lf
codereview.settings text eol=lf
DEPS text eol=lf
ENG_REVIEW_OWNERS text eol=lf
LICENSE text eol=lf
LICENSE.* text eol=lf
MAJOR_BRANCH_DATE text eol=lf
OWNERS text eol=lf
README text eol=lf
README.* text eol=lf
WATCHLISTS text eol=lf
VERSION text eol=lf
# Skip Tricium by default on files in third_party.
third_party/** -tricium

367
src/.gn Normal file
View File

@ -0,0 +1,367 @@
# This file is used by the GN meta build system to find the root of the source
# tree and to set startup options. For documentation on the values set in this
# file, run "gn help dotfile" at the command line.
import("//build/dotfile_settings.gni")
import("//third_party/angle/dotfile_settings.gni")
# The location of the build configuration file.
buildconfig = "//build/config/BUILDCONFIG.gn"
# These arguments override the default values for items in a declare_args
# block. "gn args" in turn can override these.
#
# In general the value for a build arg in the declare_args block should be the
# default. In some cases, a DEPS-ed in project will want different defaults for
# being built as part of Chrome vs. being built standalone. In this case, the
# Chrome defaults should go here. There should be no overrides here for
# values declared in the main Chrome repository.
#
# Important note for defining defaults: This file is executed before the
# BUILDCONFIG.gn file. That file sets up the global variables like "is_ios".
# This means that the default_args can not depend on the platform,
# architecture, or other build parameters. If you really need that, the other
# repo should define a flag that toggles on a behavior that implements the
# additional logic required by Chrome to set the variables.
default_args = {
# TODO(brettw) bug 684096: Chrome on iOS does not build v8, so "gn gen" prints
# a warning that "Build argument has no effect". When adding a v8 variable, it
# also needs to be defined to src/ios/BUILD.gn (respectively removed from both
# location when it is removed).
v8_extra_library_files = []
v8_experimental_extra_library_files = []
v8_enable_gdbjit = false
v8_imminent_deprecation_warnings = false
# TODO(jochen): Remove this. http://crbug.com/v8/5830,
# http://crbug.com/728583.
v8_check_microtasks_scopes_consistency = false
# Don't include webrtc's builtin task queue implementation.
rtc_link_task_queue_impl = false
# Don't include the iLBC audio codec.
# TODO(bugs.webrtc.org/8396): Once WebRTC gets rid of its internal
# deps on codecs, we can remove this.
rtc_include_ilbc = false
# Changes some setup for the Crashpad build to set them to build against
# Chromium's zlib, base, etc.
crashpad_dependencies = "chromium"
}
# These are the targets to skip header checking by default. The files in targets
# matching these patterns (see "gn help label_pattern" for format) will not have
# their includes checked for proper dependencies when you run either
# "gn check" or "gn gen --check".
no_check_targets = [
# //chrome/*, https://crbug.com/949535
"//chrome/browser/devtools:*", # 114 errors
"//chrome/browser/media/router/discovery:*", # 26 errors
"//chrome/browser/media/router:*", # 225 errors
"//chrome/browser/paint_preview:*", # 4 errors
"//chrome/browser/profiling_host:*", # 13 errors
"//chrome/browser/resources/chromeos/zip_archiver/cpp:*", # 2 errors
"//chrome/browser/safe_browsing/android:*", # 3 errors
"//chrome/browser/safe_browsing:*", # 85 errors
"//chrome/browser/safety_check/android:*", # 3 errors
"//chrome/browser/storage_access_api:*", # 2 errors
"//chrome/browser/touch_to_fill/android:*", # 8 errors
"//chrome/browser/updates/announcement_notification:*", # 15 errors
"//chrome/browser/updates/internal:*", # 8 errors
"//chrome/browser/updates:*", # 21 errors
"//chrome/install_static:*", # 4 errors
"//chrome/notification_helper:*", # 4 errors
"//chrome/renderer:*", # 42 errors
"//chrome/services/cups_proxy/public/cpp:*", # 2 errors
"//chrome/services/cups_proxy:*", # 6 errors
"//chrome/services/ipp_parser:*", # 1 error
"//chrome/services/media_gallery_util/public/cpp:*", # 6 errors
"//chrome/services/media_gallery_util:*", # 3 errors
"//chrome/services/removable_storage_writer:*", # 1 error
"//chrome/services/speech:*", # 5 errors
"//chrome/services/util_win:*", # 1 error
"//chrome/test/chromedriver:*", # 115 errors
"//chrome/test/data/nacl:*", # 350 errors
"//chrome/test/media_router:*", # 5 errors
"//chrome/test:*", # 2682 errors
"//clank/third_party/gvr_shim:*", # 1 error
"//extensions/browser/api/alarms:*", # 2 errors
"//extensions/browser/api/app_current_window_internal:*", # 3 errors
"//extensions/browser/api/app_runtime:*", # 3 errors
"//extensions/browser/api/app_window:*", # 5 errors
"//extensions/browser/api/audio:*", # 3 errors
"//extensions/browser/api/automation_internal:*", # 37 errors
"//extensions/browser/api/bluetooth_low_energy:*", # 22 errors
"//extensions/browser/api/bluetooth_socket:*", # 12 errors
"//extensions/browser/api/cast_channel:*", # 3 errors
"//extensions/browser/api/cec_private:*", # 4 errors
"//extensions/browser/api/clipboard:*", # 3 errors
"//extensions/browser/api/crash_report_private:*", # 1 error
"//extensions/browser/api/declarative:*", # 20 errors
"//extensions/browser/api/declarative_content:*", # 2 errors
"//extensions/browser/api/declarative_net_request/filter_list_converter:*", # 1
# error
"//extensions/browser/api/declarative_net_request:*", # 18 errors
"//extensions/browser/api/declarative_webrequest:*", # 29 errors
"//extensions/browser/api/diagnostics:*", # 2 errors
"//extensions/browser/api/display_source:*", # 7 errors
"//extensions/browser/api/dns:*", # 3 errors
"//extensions/browser/api/document_scan:*", # 2 errors
"//extensions/browser/api/feedback_private:*", # 2 errors
"//extensions/browser/api/file_handlers:*", # 3 errors
"//extensions/browser/api/file_system:*", # 1 error
"//extensions/browser/api/hid:*", # 12 errors
"//extensions/browser/api/idle:*", # 4 errors
"//extensions/browser/api/management:*", # 19 errors
"//extensions/browser/api/messaging:*", # 1 error
"//extensions/browser/api/metrics_private:*", # 3 errors
"//extensions/browser/api/mime_handler_private:*", # 1 error
"//extensions/browser/api/networking_config:*", # 7 errors
"//extensions/browser/api/networking_private:*", # 14 errors
"//extensions/browser/api/power:*", # 3 errors
"//extensions/browser/api/printer_provider:*", # 7 errors
"//extensions/browser/api/printer_provider_internal:*", # 3 errors
"//extensions/browser/api/runtime:*", # 6 errors
"//extensions/browser/api/serial:*", # 10 errors
"//extensions/browser/api/socket:*", # 11 errors
"//extensions/browser/api/sockets_tcp:*", # 6 errors
"//extensions/browser/api/sockets_tcp_server:*", # 8 errors
"//extensions/browser/api/sockets_udp:*", # 9 errors
"//extensions/browser/api/storage:*", # 9 errors
"//extensions/browser/api/system_cpu:*", # 1 error
"//extensions/browser/api/system_display:*", # 3 errors
"//extensions/browser/api/system_info:*", # 8 errors
"//extensions/browser/api/system_memory:*", # 1 error
"//extensions/browser/api/system_network:*", # 2 errors
"//extensions/browser/api/system_power_source:*", # 2 errors
"//extensions/browser/api/system_storage:*", # 6 errors
"//extensions/browser/api/test:*", # 1 error
"//extensions/browser/api/usb:*", # 12 errors
"//extensions/browser/api/virtual_keyboard:*", # 1 error
"//extensions/browser/api/virtual_keyboard_private:*", # 2 errors
"//extensions/browser/api/vpn_provider:*", # 13 errors
"//extensions/browser/api/web_request:*", # 37 errors
"//extensions/browser/api/webcam_private:*", # 8 errors
"//extensions/browser/api:*", # 7 errors
"//extensions/browser/updater:*", # 31 errors
"//extensions/browser/value_store:*", # 5 errors
"//extensions/browser:*", # 20 errors
"//extensions:*", # 75 errors
"//headless:*", # 167 errors
"//jingle:*", # 4 errors
"//native_client/src/trusted/service_runtime:*", # 2 errors
"//ppapi/cpp/private:*", # 1 error
"//ppapi/host:*", # 1 error
"//ppapi/native_client/src/untrusted/pnacl_irt_shim:*", # 197 errors
"//ppapi/proxy:*", # 31 errors
"//ppapi/shared_impl:*", # 3 errors
"//ppapi/thunk:*", # 1071 errors
"//ppapi:*", # 3 errors
"//remoting/base/grpc_support:*", # 14 errors
"//remoting/base/grpc_test_support:*", # 1 error
"//remoting/base:*", # 6 errors
"//remoting/client/display:*", # 55 errors
"//remoting/client/jni:*", # 8 errors
"//remoting/codec:*", # 32 errors
"//remoting/host/chromeos:*", # 10 errors
"//remoting/host/file_transfer:*", # 43 errors
"//remoting/host/input_monitor:*", # 3 errors
"//remoting/host/installer/mac:*", # 1 error
"//remoting/host/it2me:*", # 18 errors
"//remoting/host/linux:*", # 64 errors
"//remoting/host/mac:*", # 49 errors
"//remoting/host/native_messaging:*", # 3 errors
"//remoting/host/security_key:*", # 68 errors
"//remoting/host/setup:*", # 9 errors
"//remoting/host/win:*", # 43 errors
"//remoting/host:*", # 164 errors
"//remoting/ios/app/settings:*", # 6 errors
"//remoting/ios/app:*", # 9 errors
"//remoting/ios/audio:*", # 5 errors
"//remoting/ios/domain:*", # 2 errors
"//remoting/ios/facade:*", # 8 errors
"//remoting/ios/persistence:*", # 10 errors
"//remoting/ios/session:*", # 7 errors
"//remoting/ios:*", # 2 errors
"//remoting/protocol:*", # 142 errors
"//remoting/signaling:*", # 30 errors
"//remoting/test:*", # 20 errors
"//remoting:*", # 27 errors
"//sandbox/linux:*", # 13 errors
"//sandbox/mac:*", # 14 errors
"//sandbox/win:*", # 7 errors
# //third_party/blink/*, https://crbug.com/800764
"//third_party/blink/renderer/core/accessibility:*", # 27 errors
"//third_party/blink/renderer/core/animation:*", # 506 errors
"//third_party/blink/renderer/core/animation_frame:*", # 4 errors
"//third_party/blink/renderer/core/aom:*", # 23 errors
"//third_party/blink/renderer/core/clipboard:*", # 43 errors
"//third_party/blink/renderer/core/content_capture:*", # 12 errors
"//third_party/blink/renderer/core/context_features:*", # 3 errors
"//third_party/blink/renderer/core/css:*", # 835 errors
"//third_party/blink/renderer/core/display_lock:*", # 36 errors
"//third_party/blink/renderer/core/dom:*", # 706 errors
"//third_party/blink/renderer/core/editing:*", # 847 errors
"//third_party/blink/renderer/core/events:*", # 173 errors
"//third_party/blink/renderer/core/execution_context:*", # 48 errors
"//third_party/blink/renderer/core/exported:*", # 470 errors
"//third_party/blink/renderer/core/feature_policy:*", # 15 errors
"//third_party/blink/renderer/core/fetch:*", # 134 errors
"//third_party/blink/renderer/core/fileapi:*", # 55 errors
"//third_party/blink/renderer/core/frame:*", # 864 errors
"//third_party/blink/renderer/core/fullscreen:*", # 32 errors
"//third_party/blink/renderer/core/geometry:*", # 39 errors
"//third_party/blink/renderer/core/html/parser:*", # 133 errors
"//third_party/blink/renderer/core/html:*", # 1662 errors
"//third_party/blink/renderer/core/imagebitmap:*", # 34 errors
"//third_party/blink/renderer/core/input:*", # 240 errors
"//third_party/blink/renderer/core/inspector:*", # 594 errors
"//third_party/blink/renderer/core/intersection_observer:*", # 50 errors
"//third_party/blink/renderer/core/layout/svg:*", # 193 errors
"//third_party/blink/renderer/core/layout:*", # 920 errors
"//third_party/blink/renderer/core/loader:*", # 421 errors
"//third_party/blink/renderer/core/mathml:*", # 11 errors
"//third_party/blink/renderer/core/messaging:*", # 30 errors
"//third_party/blink/renderer/core/offscreencanvas:*", # 22 errors
"//third_party/blink/renderer/core/origin_trials:*", # 12 errors
"//third_party/blink/renderer/core/page:*", # 500 errors
"//third_party/blink/renderer/core/paint:*", # 788 errors
"//third_party/blink/renderer/core/probe:*", # 9 errors
"//third_party/blink/renderer/core/resize_observer:*", # 29 errors
"//third_party/blink/renderer/core/script:*", # 155 errors
"//third_party/blink/renderer/core/scroll:*", # 29 errors
"//third_party/blink/renderer/core/streams:*", # 75 errors
"//third_party/blink/renderer/core/style:*", # 86 errors
"//third_party/blink/renderer/core/svg:*", # 297 errors
"//third_party/blink/renderer/core/timezone:*", # 8 errors
"//third_party/blink/renderer/core/timing:*", # 170 errors
"//third_party/blink/renderer/core/trustedtypes:*", # 27 errors
"//third_party/blink/renderer/core/typed_arrays:*", # 24 errors
"//third_party/blink/renderer/core/url:*", # 7 errors
"//third_party/blink/renderer/core/workers:*", # 289 errors
"//third_party/blink/renderer/core/xmlhttprequest:*", # 49 errors
"//third_party/blink/renderer/core:*", # 823 errors
"//third_party/blink/renderer/modules/peerconnection:*", # 43 errors
"//third_party/breakpad:*", # 34 errors
"//third_party/ced/*",
"//third_party/crashpad/crashpad/client:*", # 1 error
"//third_party/crashpad/crashpad/compat:*", # 2 errors
"//third_party/crashpad/crashpad/snapshot:*", # 1 error
"//third_party/crashpad/crashpad/test:*", # 2 errors
"//third_party/crashpad/crashpad/util:*", # 2 errors
"//third_party/dav1d:*", # 95 errors
"//third_party/ffmpeg:*", # 1 error
"//third_party/icu/*",
"//third_party/libvpx:*", # 164 errors
"//third_party/libwebp:*", # 80 errors, https://crbug.com/800762
"//third_party/openscreen/src/cast/common:*", # 4 errors
"//third_party/openscreen/src/cast/receiver:*", # 1 error
"//third_party/openscreen/src/cast/streaming:*", # 66 errors
"//third_party/openscreen/src/discovery:*", # 36 errors
"//third_party/openscreen/src/osp/impl/quic:*", # 16 errors
"//third_party/openscreen/src/osp/msgs:*", # 5 errors
"//third_party/openscreen/src/osp/public:*", # 1 error
"//third_party/openscreen/src/osp:*", # 13 errors
"//third_party/openscreen/src/util:*", # 29 errors
"//third_party/pdfium/samples:*", # 1 error
"//third_party/pdfium/third_party:*", # 2 errors
"//third_party/pdfium:*", # 1 error
# //v8/*, https://crbug.com/v8/7330
"//v8/src/inspector:*", # 20 errors
"//v8/test/cctest:*", # 26 errors
"//v8/test/unittests:*", # 11 errors
"//v8/test/wasm-api-tests:*", # 13 errors
"//v8/third_party/inspector_protocol:*", # 2 errors
"//v8/tools/debug_helper:*", # 9 errors
"//v8/tools/v8windbg:*", # 2 errors
"//v8:*", # 1871 errors
]
# These are the list of GN files that run exec_script. This whitelist exists
# to force additional review for new uses of exec_script, which is strongly
# discouraged.
#
# PLEASE READ
#
# You should almost never need to add new exec_script calls. exec_script is
# slow, especially on Windows, and can cause confusing effects. Although
# individually each call isn't slow or necessarily very confusing, at the scale
# of our repo things get out of hand quickly. By strongly pushing back on all
# additions, we keep the build fast and clean. If you think you need to add a
# new call, please consider:
#
# - Do not use a script to check for the existence of a file or directory to
# enable a different mode. Instead, use GN build args to enable or disable
# functionality and set options. An example is checking for a file in the
# src-internal repo to see if the corresponding src-internal feature should
# be enabled. There are several things that can go wrong with this:
#
# - It's mysterious what causes some things to happen. Although in many cases
# such behavior can be conveniently automatic, GN optimizes for explicit
# and obvious behavior so people can more easily diagnose problems.
#
# - The user can't enable a mode for one build and not another. With GN build
# args, the user can choose the exact configuration of multiple builds
# using one checkout. But implicitly basing flags on the state of the
# checkout, this functionality is broken.
#
# - It's easy to get stale files. If for example the user edits the gclient
# to stop checking out src-internal (or any other optional thing), it's
# easy to end up with stale files still mysteriously triggering build
# conditions that are no longer appropriate (yes, this happens in real
# life).
#
# - Do not use a script to iterate files in a directory (glob):
#
# - This has the same "stale file" problem as the above discussion. Various
# operations can leave untracked files in the source tree which can cause
# surprising effects.
#
# - It becomes impossible to use "git grep" to find where a certain file is
# referenced. This operation is very common and people really do get
# confused when things aren't listed.
#
# - It's easy to screw up. One common case is a build-time script that packs
# up a directory. The author notices that the script isn't re-run when the
# directory is updated, so adds a glob so all the files are listed as
# inputs. This seems to work great... until a file is deleted. When a
# file is deleted, all the inputs the glob lists will still be up to date
# and no command-lines will have been changed. The action will not be
# re-run and the build will be broken. It is possible to get this correct
# using glob, and it's possible to mess it up without glob, but globs make
# this situation much easier to create. if the build always lists the
# files and passes them to a script, it will always be correct.
exec_script_whitelist =
build_dotfile_settings.exec_script_whitelist +
angle_dotfile_settings.exec_script_whitelist +
[
# Whitelist entries for //build should go into
# //build/dotfile_settings.gni instead, so that they can be shared
# with other repos. The entries in this list should be only for files
# in the Chromium repo outside of //build.
"//build_overrides/build.gni",
"//chrome/android/webapk/shell_apk/prepare_upload_dir/BUILD.gn",
# TODO(dgn): Layer violation but breaks the build otherwise, see
# https://crbug.com/474506.
"//clank/java/BUILD.gn",
"//clank/native/BUILD.gn",
"//google_apis/BUILD.gn",
"//printing/BUILD.gn",
"//remoting/host/installer/linux/BUILD.gn",
"//remoting/remoting_version.gni",
"//remoting/host/installer/win/generate_clsids.gni",
"//tools/grit/grit_rule.gni",
"//tools/gritsettings/BUILD.gn",
]

1218
src/AUTHORS Normal file

File diff suppressed because it is too large Load Diff

1424
src/BUILD.gn Normal file

File diff suppressed because it is too large Load Diff

27
src/LICENSE Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

1027
src/android_webview/BUILD.gn Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,269 @@
# 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.
import("//build/config/android/rules.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
java_cpp_enum("browser_enums") {
sources = [
"aw_renderer_priority.h",
"aw_settings.h",
"permission/aw_permission_request.h",
"safe_browsing/aw_safe_browsing_blocking_page.h",
"safe_browsing/aw_url_checker_delegate_impl.h",
]
}
source_set("browser") {
sources = [
"android_protocol_handler.cc",
"android_protocol_handler.h",
"aw_autofill_client.cc",
"aw_autofill_client.h",
"aw_browser_context.cc",
"aw_browser_context.h",
"aw_browser_main_parts.cc",
"aw_browser_main_parts.h",
"aw_browser_permission_request_delegate.h",
"aw_browser_policy_connector.cc",
"aw_browser_policy_connector.h",
"aw_browser_process.cc",
"aw_browser_process.h",
"aw_browser_terminator.cc",
"aw_browser_terminator.h",
"aw_content_browser_client.cc",
"aw_content_browser_client.h",
"aw_content_browser_client_receiver_bindings.cc",
"aw_contents.cc",
"aw_contents.h",
"aw_contents_client_bridge.cc",
"aw_contents_client_bridge.h",
"aw_contents_io_thread_client.cc",
"aw_contents_io_thread_client.h",
"aw_contents_statics.cc",
"aw_cookie_access_policy.cc",
"aw_cookie_access_policy.h",
"aw_debug.cc",
"aw_devtools_manager_delegate.cc",
"aw_devtools_manager_delegate.h",
"aw_devtools_server.cc",
"aw_devtools_server.h",
"aw_download_manager_delegate.cc",
"aw_download_manager_delegate.h",
"aw_feature_list.cc",
"aw_feature_list_creator.cc",
"aw_feature_list_creator.h",
"aw_field_trials.cc",
"aw_field_trials.h",
"aw_form_database.cc",
"aw_form_database_service.cc",
"aw_form_database_service.h",
"aw_http_auth_handler.cc",
"aw_http_auth_handler.h",
"aw_javascript_dialog_manager.cc",
"aw_javascript_dialog_manager.h",
"aw_media_url_interceptor.cc",
"aw_media_url_interceptor.h",
"aw_metrics_service_client_delegate.cc",
"aw_metrics_service_client_delegate.h",
"aw_pac_processor.cc",
"aw_pac_processor.h",
"aw_pdf_exporter.cc",
"aw_pdf_exporter.h",
"aw_permission_manager.cc",
"aw_permission_manager.h",
"aw_print_manager.cc",
"aw_print_manager.h",
"aw_proxy_controller.cc",
"aw_quota_manager_bridge.cc",
"aw_quota_manager_bridge.h",
"aw_quota_permission_context.cc",
"aw_quota_permission_context.h",
"aw_render_process.cc",
"aw_render_process.h",
"aw_render_process_gone_delegate.h",
"aw_renderer_priority.h",
"aw_resource_context.cc",
"aw_resource_context.h",
"aw_settings.cc",
"aw_settings.h",
"aw_speech_recognition_manager_delegate.cc",
"aw_speech_recognition_manager_delegate.h",
"aw_ssl_host_state_delegate.cc",
"aw_ssl_host_state_delegate.h",
"aw_variations_service_client.cc",
"aw_variations_service_client.h",
"aw_web_contents_delegate.cc",
"aw_web_contents_delegate.h",
"aw_web_contents_view_delegate.cc",
"aw_web_contents_view_delegate.h",
"aw_web_ui_controller_factory.cc",
"aw_web_ui_controller_factory.h",
"cookie_manager.cc",
"cookie_manager.h",
"find_helper.cc",
"find_helper.h",
"icon_helper.cc",
"icon_helper.h",
"js_java_interaction/aw_web_message_host_factory.cc",
"js_java_interaction/aw_web_message_host_factory.h",
"js_java_interaction/js_reply_proxy.cc",
"js_java_interaction/js_reply_proxy.h",
"network_service/aw_network_change_notifier.cc",
"network_service/aw_network_change_notifier.h",
"network_service/aw_network_change_notifier_factory.cc",
"network_service/aw_network_change_notifier_factory.h",
"network_service/aw_proxy_config_monitor.cc",
"network_service/aw_proxy_config_monitor.h",
"network_service/aw_proxying_restricted_cookie_manager.cc",
"network_service/aw_proxying_restricted_cookie_manager.h",
"network_service/aw_proxying_url_loader_factory.cc",
"network_service/aw_proxying_url_loader_factory.h",
"network_service/aw_url_loader_throttle.cc",
"network_service/aw_url_loader_throttle.h",
"network_service/aw_web_resource_intercept_response.cc",
"network_service/aw_web_resource_intercept_response.h",
"network_service/aw_web_resource_request.cc",
"network_service/aw_web_resource_request.h",
"network_service/net_helpers.cc",
"network_service/net_helpers.h",
"page_load_metrics/aw_page_load_metrics_provider.cc",
"page_load_metrics/aw_page_load_metrics_provider.h",
"page_load_metrics/page_load_metrics_initialize.cc",
"page_load_metrics/page_load_metrics_initialize.h",
"permission/aw_permission_request.cc",
"permission/aw_permission_request.h",
"permission/aw_permission_request_delegate.cc",
"permission/aw_permission_request_delegate.h",
"permission/media_access_permission_request.cc",
"permission/media_access_permission_request.h",
"permission/permission_request_handler.cc",
"permission/permission_request_handler.h",
"permission/permission_request_handler_client.cc",
"permission/permission_request_handler_client.h",
"permission/simple_permission_request.cc",
"permission/simple_permission_request.h",
"popup_touch_handle_drawable.cc",
"popup_touch_handle_drawable.h",
"renderer_host/auto_login_parser.cc",
"renderer_host/auto_login_parser.h",
"renderer_host/aw_render_view_host_ext.cc",
"renderer_host/aw_render_view_host_ext.h",
"safe_browsing/aw_safe_browsing_allowlist_manager.cc",
"safe_browsing/aw_safe_browsing_allowlist_manager.h",
"safe_browsing/aw_safe_browsing_blocking_page.cc",
"safe_browsing/aw_safe_browsing_blocking_page.h",
"safe_browsing/aw_safe_browsing_navigation_throttle.cc",
"safe_browsing/aw_safe_browsing_navigation_throttle.h",
"safe_browsing/aw_safe_browsing_subresource_helper.cc",
"safe_browsing/aw_safe_browsing_subresource_helper.h",
"safe_browsing/aw_safe_browsing_ui_manager.cc",
"safe_browsing/aw_safe_browsing_ui_manager.h",
"safe_browsing/aw_url_checker_delegate_impl.cc",
"safe_browsing/aw_url_checker_delegate_impl.h",
"scoped_add_feature_flags.cc",
"scoped_add_feature_flags.h",
"state_serializer.cc",
"state_serializer.h",
"tracing/aw_trace_event_args_allowlist.cc",
"tracing/aw_trace_event_args_allowlist.h",
"tracing/aw_tracing_controller.cc",
"tracing/aw_tracing_controller.h",
"tracing/aw_tracing_delegate.cc",
"tracing/aw_tracing_delegate.h",
"variations_seed_loader.cc",
"variations_seed_loader.h",
]
deps = [
"//android_webview:browser_jni_headers",
"//android_webview:generate_components_strings",
"//android_webview/browser/gfx",
"//android_webview/browser/lifecycle",
"//android_webview/browser/metrics",
"//android_webview/common",
"//android_webview/proto:aw_variations_seed_proto",
"//base",
"//components/autofill/android/provider",
"//components/autofill/content/browser",
"//components/cdm/browser",
"//components/content_capture/android",
"//components/content_capture/browser",
"//components/embedder_support/android:util",
"//components/favicon_base:favicon_base",
"//components/flags_ui",
# Called via JNI in CrashpadMain
"//components/crash/android:crashpad_main",
"//components/crash/content/browser",
"//components/crash/core/app",
"//components/embedder_support/android:web_contents_delegate",
"//components/embedder_support/android/metrics",
"//components/google/core/common",
"//components/heap_profiling/multi_process",
"//components/js_injection/browser",
"//components/js_injection/common",
"//components/js_injection/common:common_mojom",
"//components/metrics",
"//components/minidump_uploader",
"//components/navigation_interception",
"//components/page_load_metrics/browser",
"//components/policy/content/",
"//components/policy/core/browser",
"//components/power_metrics",
"//components/pref_registry",
"//components/prefs",
"//components/printing/browser",
"//components/printing/common",
"//components/printing/common:mojo_interfaces",
"//components/safe_browsing/android:remote_database_manager",
"//components/safe_browsing/content",
"//components/safe_browsing/content/browser",
"//components/safe_browsing/content/common:interfaces",
"//components/safe_browsing/content/web_ui",
"//components/safe_browsing/core:features",
"//components/safe_browsing/core:ping_manager",
"//components/safe_browsing/core/browser",
"//components/safe_browsing/core/browser:network_context",
"//components/safe_browsing/core/common",
"//components/safe_browsing/core/db:database_manager",
"//components/safe_browsing/core/db:safebrowsing_proto",
"//components/safe_browsing/core/triggers",
"//components/safe_browsing/core/web_ui:constants",
"//components/security_interstitials/content:security_interstitial_page",
"//components/security_interstitials/core",
"//components/services/heap_profiling/public/cpp",
"//components/spellcheck:buildflags",
"//components/url_formatter",
"//components/user_prefs",
"//components/variations",
"//components/variations/net",
"//components/variations/service",
"//components/version_info",
"//components/version_info/android:channel_getter",
"//components/visitedlink/browser",
"//components/webdata/common",
"//content/public/browser",
"//media/mojo:buildflags",
"//printing",
"//services/preferences/tracked",
"//services/proxy_resolver:lib",
"//third_party/blink/public/common",
"//third_party/blink/public/mojom/frame",
"//third_party/crashpad/crashpad/client",
"//ui/android",
"//ui/gl",
"//ui/resources",
"//ui/touch_selection",
]
if (enable_spellcheck) {
deps += [ "//components/spellcheck/browser" ]
}
configs += [
"//tools/v8_context_snapshot:use_v8_context_snapshot",
"//v8:external_startup_data",
]
}

View File

@ -0,0 +1,102 @@
# 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.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
source_set("gfx") {
sources = [
"aw_attaching_to_window_recorder.cc",
"aw_attaching_to_window_recorder.h",
"aw_draw_fn_impl.cc",
"aw_draw_fn_impl.h",
"aw_gl_functor.cc",
"aw_gl_functor.h",
"aw_gl_surface.cc",
"aw_gl_surface.h",
"aw_gl_surface_external_stencil.cc",
"aw_gl_surface_external_stencil.h",
"aw_picture.cc",
"aw_picture.h",
"aw_render_thread_context_provider.cc",
"aw_render_thread_context_provider.h",
"aw_vulkan_context_provider.cc",
"aw_vulkan_context_provider.h",
"begin_frame_source_webview.cc",
"begin_frame_source_webview.h",
"browser_view_renderer.cc",
"browser_view_renderer.h",
"browser_view_renderer_client.h",
"child_frame.cc",
"child_frame.h",
"compositor_frame_consumer.h",
"compositor_frame_producer.h",
"deferred_gpu_command_service.cc",
"deferred_gpu_command_service.h",
"display_scheduler_webview.cc",
"display_scheduler_webview.h",
"gpu_service_web_view.cc",
"gpu_service_web_view.h",
"hardware_renderer.cc",
"hardware_renderer.h",
"hardware_renderer_single_thread.cc",
"hardware_renderer_single_thread.h",
"hardware_renderer_viz.cc",
"hardware_renderer_viz.h",
"java_browser_view_renderer_helper.cc",
"java_browser_view_renderer_helper.h",
"output_surface_provider_webview.cc",
"output_surface_provider_webview.h",
"parent_compositor_draw_constraints.cc",
"parent_compositor_draw_constraints.h",
"parent_output_surface.cc",
"parent_output_surface.h",
"render_thread_manager.cc",
"render_thread_manager.h",
"root_frame_sink.cc",
"root_frame_sink.h",
"root_frame_sink_proxy.cc",
"root_frame_sink_proxy.h",
"scoped_app_gl_state_restore.cc",
"scoped_app_gl_state_restore.h",
"skia_output_surface_dependency_webview.cc",
"skia_output_surface_dependency_webview.h",
"surfaces_instance.cc",
"surfaces_instance.h",
"task_forwarding_sequence.cc",
"task_forwarding_sequence.h",
"task_queue_web_view.cc",
"task_queue_web_view.h",
"viz_compositor_thread_runner_webview.cc",
"viz_compositor_thread_runner_webview.h",
]
deps = [
"//android_webview:browser_jni_headers",
"//android_webview/common",
"//android_webview/public",
"//base",
"//components/ui_devtools:buildflags",
"//components/viz/service",
"//components/viz/service/main",
"//content/public/browser",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/service",
"//gpu/ipc:gl_in_process_context",
"//gpu/ipc/common:android_image_reader_utils",
"//gpu/ipc/common:common",
"//gpu/skia_bindings",
"//gpu/vulkan:vulkan",
"//gpu/vulkan/init",
"//gpu/vulkan/init:skia",
"//services/viz/privileged/mojom",
"//services/viz/public/mojom",
"//skia",
"//ui/gfx",
"//ui/gl",
"//ui/gl/init",
]
libs = [ "jnigraphics" ]
}

View File

@ -0,0 +1,17 @@
# Copyright 2020 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.
source_set("lifecycle") {
sources = [
"aw_contents_lifecycle_notifier.cc",
"aw_contents_lifecycle_notifier.h",
"webview_app_state_observer.cc",
"webview_app_state_observer.h",
]
deps = [
"//android_webview:browser_jni_headers",
"//base",
"//content/public/browser",
]
}

View File

@ -0,0 +1,27 @@
# 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.
source_set("metrics") {
sources = [
"aw_metrics_service_client.cc",
"aw_metrics_service_client.h",
"aw_stability_metrics_provider.cc",
"aw_stability_metrics_provider.h",
"visibility_metrics_logger.cc",
"visibility_metrics_logger.h",
"visibility_metrics_provider.cc",
"visibility_metrics_provider.h",
]
deps = [
"//android_webview:browser_jni_headers",
"//android_webview/browser/lifecycle",
"//android_webview/common",
"//base",
"//components/embedder_support/android/metrics",
"//components/metrics",
"//components/prefs",
"//components/version_info/android:channel_getter",
"//content/public/browser",
]
}

View File

@ -0,0 +1,61 @@
# 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.
import("//build/config/android/rules.gni")
import("//mojo/public/tools/bindings/mojom.gni")
source_set("common") {
sources = [
"android_webview_message_generator.cc",
"android_webview_message_generator.h",
"aw_content_client.cc",
"aw_content_client.h",
"aw_descriptors.h",
"aw_features.cc",
"aw_features.h",
"aw_hit_test_data.cc",
"aw_hit_test_data.h",
"aw_media_drm_bridge_client.cc",
"aw_media_drm_bridge_client.h",
"aw_paths.cc",
"aw_paths.h",
"aw_resource.cc",
"aw_resource.h",
"aw_resource_bundle.cc",
"aw_resource_bundle.h",
"aw_switches.cc",
"aw_switches.h",
"crash_reporter/aw_crash_reporter_client.cc",
"crash_reporter/aw_crash_reporter_client.h",
"crash_reporter/crash_keys.cc",
"crash_reporter/crash_keys.h",
"devtools_instrumentation.h",
"render_view_messages.cc",
"render_view_messages.h",
"url_constants.cc",
"url_constants.h",
]
deps = [
"//android_webview:common_jni_headers",
"//base",
"//components/cdm/common",
"//components/crash/core/app",
"//components/crash/core/common:crash_key",
"//components/gwp_asan/common",
"//components/services/heap_profiling/public/cpp",
"//components/version_info",
"//components/version_info:generate_version_info",
"//components/version_info/android:channel_getter",
"//content/public/common",
"//gpu/config",
"//ipc",
"//mojo/public/cpp/bindings",
"//skia",
"//ui/base",
"//ui/gfx/geometry",
"//ui/gfx/ipc/geometry",
"//ui/gfx/ipc/skia",
"//url",
]
}

View File

@ -0,0 +1,86 @@
# Copyright 2015 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.
import("//android_webview/system_webview_apk_tmpl.gni")
import("//android_webview/variables.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("glue_java") {
deps = [
"//android_webview:android_webview_product_config_java",
"//android_webview:browser_java",
"//android_webview:common_java",
"//android_webview/nonembedded:system_webview_manifest",
"//android_webview/support_library/boundary_interfaces:boundary_interface_java",
"//android_webview/support_library/callback:callback_java",
"//base:base_java",
"//base:jni_java",
"//components/autofill/android:autofill_java",
"//components/autofill/android/provider:java",
"//components/content_capture/android:java",
"//components/embedder_support/android:application_java",
"//components/embedder_support/android:util_java",
"//content/public/android:content_java",
"//net/android:net_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//ui/android:ui_no_recycler_view_java",
"//url:gurl_java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
alternative_android_sdk_dep =
"//third_party/android_sdk:public_framework_system_java"
sources = [
"java/src/com/android/webview/chromium/CallbackConverter.java",
"java/src/com/android/webview/chromium/ContentSettingsAdapter.java",
"java/src/com/android/webview/chromium/CookieManagerAdapter.java",
"java/src/com/android/webview/chromium/DrawFunctor.java",
"java/src/com/android/webview/chromium/DrawGLFunctor.java",
"java/src/com/android/webview/chromium/GeolocationPermissionsAdapter.java",
"java/src/com/android/webview/chromium/GlueApiHelperForM.java",
"java/src/com/android/webview/chromium/GlueApiHelperForN.java",
"java/src/com/android/webview/chromium/GlueApiHelperForO.java",
"java/src/com/android/webview/chromium/GlueApiHelperForOMR1.java",
"java/src/com/android/webview/chromium/GlueApiHelperForP.java",
"java/src/com/android/webview/chromium/GlueApiHelperForQ.java",
"java/src/com/android/webview/chromium/GlueApiHelperForR.java",
"java/src/com/android/webview/chromium/GraphicsUtils.java",
"java/src/com/android/webview/chromium/MonochromeLibraryPreloader.java",
"java/src/com/android/webview/chromium/PacProcessorImpl.java",
"java/src/com/android/webview/chromium/SafeBrowsingResponseAdapter.java",
"java/src/com/android/webview/chromium/ServiceWorkerClientAdapter.java",
"java/src/com/android/webview/chromium/ServiceWorkerControllerAdapter.java",
"java/src/com/android/webview/chromium/ServiceWorkerSettingsAdapter.java",
"java/src/com/android/webview/chromium/SharedStatics.java",
"java/src/com/android/webview/chromium/SharedTracingControllerAdapter.java",
"java/src/com/android/webview/chromium/SharedWebViewChromium.java",
"java/src/com/android/webview/chromium/SharedWebViewContentsClientAdapter.java",
"java/src/com/android/webview/chromium/SharedWebViewRendererClientAdapter.java",
"java/src/com/android/webview/chromium/SplitApkWorkaround.java",
"java/src/com/android/webview/chromium/TracingControllerAdapter.java",
"java/src/com/android/webview/chromium/WebBackForwardListChromium.java",
"java/src/com/android/webview/chromium/WebHistoryItemChromium.java",
"java/src/com/android/webview/chromium/WebIconDatabaseAdapter.java",
"java/src/com/android/webview/chromium/WebMessagePortAdapter.java",
"java/src/com/android/webview/chromium/WebResourceErrorAdapter.java",
"java/src/com/android/webview/chromium/WebResourceRequestAdapter.java",
"java/src/com/android/webview/chromium/WebStorageAdapter.java",
"java/src/com/android/webview/chromium/WebViewChromium.java",
"java/src/com/android/webview/chromium/WebViewChromiumAwInit.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProviderForO.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProviderForOMR1.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProviderForP.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProviderForQ.java",
"java/src/com/android/webview/chromium/WebViewChromiumFactoryProviderForR.java",
"java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java",
"java/src/com/android/webview/chromium/WebViewDatabaseAdapter.java",
"java/src/com/android/webview/chromium/WebViewDelegateFactory.java",
"java/src/com/android/webview/chromium/WebViewRenderProcessAdapter.java",
"java/src/com/android/webview/chromium/WebViewRenderProcessClientAdapter.java",
"java/src/com/android/webview/chromium/WebkitToSharedGlueConverter.java",
]
}

View File

@ -0,0 +1,15 @@
# 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.
source_set("gpu") {
sources = [
"aw_content_gpu_client.cc",
"aw_content_gpu_client.h",
]
deps = [
"//base",
"//content/public/gpu",
]
}

View File

@ -0,0 +1,70 @@
# 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.
import("//components/gwp_asan/buildflags/buildflags.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
import("//weblayer/variables.gni")
source_set("lib") {
sources = [
"aw_main_delegate.cc",
"aw_main_delegate.h",
"webview_jni_onload.cc",
"webview_jni_onload.h",
]
deps = [
"//android_webview/browser",
"//android_webview/browser/gfx",
"//android_webview/common",
"//android_webview/gpu",
"//android_webview/renderer",
"//base",
"//cc/base",
"//components/autofill/core/common",
"//components/crash/core/common",
"//components/gwp_asan/buildflags",
"//components/metrics",
"//components/safe_browsing/android:safe_browsing_api_handler",
"//components/services/heap_profiling/public/cpp",
"//components/spellcheck:buildflags",
"//components/version_info",
"//components/version_info/android:channel_getter",
"//components/viz/common",
"//content/public/app",
"//content/public/browser",
"//content/public/common",
"//content/public/common:content_descriptor_keys",
"//content/public/common:service_names",
"//gin",
"//gpu/command_buffer/service",
"//gpu/config",
"//gpu/ipc:gl_in_process_context",
"//media",
"//media:media_buildflags",
"//ui/base",
"//ui/events:gesture_detection",
]
if (enable_gwp_asan) {
deps += [ "//components/gwp_asan/client" ]
}
if (enable_spellcheck) {
deps += [ "//components/spellcheck/common" ]
}
}
source_set("webview_entry_point") {
deps = [
":lib",
"//base",
]
sources = [ "webview_entry_point.cc" ]
if (webview_includes_weblayer) {
defines = [ "WEBVIEW_INCLUDES_WEBLAYER" ]
deps += [ "//weblayer:weblayer_lib_webview" ]
}
}

View File

@ -0,0 +1,211 @@
# Copyright 2017 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.
import("//android_webview/system_webview_apk_tmpl.gni")
import("//android_webview/variables.gni")
import("//build/config/android/rules.gni")
generate_jni("nonembedded_jni_headers") {
sources = [ "java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java" ]
}
# Contains classes needed by the webview apk, but not used when loading the apk
# as a library.
android_library("nonembedded_java") {
sources = [
"java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java",
"java/src/org/chromium/android_webview/nonembedded/LicenseActivity.java",
"java/src/org/chromium/android_webview/nonembedded/LicenseContentProvider.java",
"java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java",
]
deps = [
":devui_java",
":services_java",
"//android_webview:android_webview_product_config_java",
"//android_webview:common_aidl_java",
"//android_webview:common_java",
"//android_webview/proto:metrics_bridge_records_proto_java",
"//base:base_java",
"//base:jni_java",
"//components/about_ui/android:aboutui_java",
"//components/embedder_support/android:application_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:com_google_code_findbugs_jsr305_java",
"//third_party/android_deps:protobuf_lite_runtime_java",
"//ui/android:ui_no_recycler_view_java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
android_library("devui_java") {
sources = [
"java/src/org/chromium/android_webview/devui/CrashesListFragment.java",
"java/src/org/chromium/android_webview/devui/DevUiBaseFragment.java",
"java/src/org/chromium/android_webview/devui/FlagsFragment.java",
"java/src/org/chromium/android_webview/devui/HomeFragment.java",
"java/src/org/chromium/android_webview/devui/MainActivity.java",
"java/src/org/chromium/android_webview/devui/PersistentErrorView.java",
"java/src/org/chromium/android_webview/devui/WebViewPackageError.java",
"java/src/org/chromium/android_webview/devui/util/CrashBugUrlFactory.java",
"java/src/org/chromium/android_webview/devui/util/CrashInfoLoader.java",
"java/src/org/chromium/android_webview/devui/util/UnuploadedFilesStateLoader.java",
"java/src/org/chromium/android_webview/devui/util/UploadedCrashesInfoLoader.java",
"java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java",
"java/src/org/chromium/android_webview/devui/util/WebViewCrashLogParser.java",
"java/src/org/chromium/android_webview/devui/util/WebViewPackageHelper.java",
]
deps = [
":devui_resources",
":system_webview_manifest",
"//android_webview:common_aidl_java",
"//android_webview:common_crash_java",
"//android_webview:common_java",
"//android_webview:common_platform_services_java",
"//base:base_java",
"//components/minidump_uploader:minidump_uploader_java",
"//components/version_info/android:version_constants_java",
"//third_party/android_deps:androidx_activity_activity_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_core_core_java",
"//third_party/android_deps:androidx_fragment_fragment_java",
"//third_party/android_deps:androidx_lifecycle_lifecycle_common_java",
"//third_party/android_deps:androidx_lifecycle_lifecycle_viewmodel_java",
"//third_party/android_deps:androidx_savedstate_savedstate_java",
"//ui/android:ui_no_recycler_view_java",
]
resources_package = "org.chromium.android_webview.devui"
}
android_library("services_java") {
sources = [
"java/src/org/chromium/android_webview/services/AwMinidumpUploadJobService.java",
"java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java",
"java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java",
"java/src/org/chromium/android_webview/services/CrashReceiverService.java",
"java/src/org/chromium/android_webview/services/DeveloperModeContentProvider.java",
"java/src/org/chromium/android_webview/services/DeveloperUiService.java",
"java/src/org/chromium/android_webview/services/MetricsBridgeService.java",
"java/src/org/chromium/android_webview/services/VariationsSeedHolder.java",
"java/src/org/chromium/android_webview/services/VariationsSeedServer.java",
]
deps = [
":system_webview_manifest",
"//android_webview:common_aidl_java",
"//android_webview:common_crash_java",
"//android_webview:common_java",
"//android_webview:common_platform_services_java",
"//android_webview:common_variations_java",
"//android_webview/proto:metrics_bridge_records_proto_java",
"//base:base_java",
"//components/background_task_scheduler:background_task_scheduler_task_ids_java",
"//components/minidump_uploader:minidump_uploader_java",
"//components/variations/android:variations_java",
"//components/version_info/android:version_constants_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:com_google_code_findbugs_jsr305_java",
"//third_party/android_deps:protobuf_lite_runtime_java",
]
}
source_set("nonembedded") {
sources = [ "webview_apk_application.cc" ]
deps = [
":nonembedded_jni_headers",
"//android_webview/common",
"//base",
# Called via JNI by LicenseContentProvider in :nonembedded_java.
"//components/about_ui:about_ui_android",
]
}
# WebView icon used by upstream SystemWebView and Trichrome.
android_resources("icon_resources") {
sources = [
"java/res_icon/drawable-hdpi/icon_webview.png",
"java/res_icon/drawable-mdpi/icon_webview.png",
"java/res_icon/drawable-xhdpi/icon_webview.png",
"java/res_icon/drawable-xxhdpi/icon_webview.png",
]
}
android_resources("devui_resources") {
sources = [
"java/res_devui/drawable/blue_circle.xml",
"java/res_devui/drawable/ic_action_home.xml",
"java/res_devui/drawable/ic_alert_error.xml",
"java/res_devui/drawable/ic_clear_text.xml",
"java/res_devui/drawable/ic_delete.xml",
"java/res_devui/drawable/ic_devui_search.xml",
"java/res_devui/drawable/ic_flag.xml",
"java/res_devui/layout/activity_main.xml",
"java/res_devui/layout/crashes_list_item_body.xml",
"java/res_devui/layout/crashes_list_item_header.xml",
"java/res_devui/layout/flag_states.xml",
"java/res_devui/layout/flag_ui_warning.xml",
"java/res_devui/layout/fragment_crashes_list.xml",
"java/res_devui/layout/fragment_flags.xml",
"java/res_devui/layout/fragment_home.xml",
"java/res_devui/layout/persistent_error_message.xml",
"java/res_devui/layout/toggleable_flag.xml",
"java/res_devui/layout/two_line_list_item.xml",
"java/res_devui/layout/two_line_sublist_item.xml",
"java/res_devui/menu/crashes_options_menu.xml",
"java/res_devui/menu/options_menu.xml",
"java/res_devui/values-night/colors.xml",
"java/res_devui/values-night/styles.xml",
"java/res_devui/values/colors.xml",
"java/res_devui/values/strings.xml",
"java/res_devui/values/styles.xml",
]
}
android_resources("devui_launcher_icon_resources") {
sources = []
android_manifest = "java/DeveloperUiLauncherManifest.xml"
}
android_resources("monochrome_devui_launcher_icon_resources") {
sources = []
android_manifest = "java/MonochromeDeveloperUiLauncherManifest.xml"
}
_webview_jinja_variables = [ "manifest_package=$system_webview_package_name" ] +
webview_jinja_variables
jinja_template("system_webview_manifest") {
input = "java/AndroidManifest.xml"
output = system_webview_android_manifest
variables = _webview_jinja_variables
}
jinja_template("trichrome_webview_manifest") {
input = "java/AndroidManifest.xml"
output = trichrome_webview_android_manifest
variables = trichrome_jinja_variables + _webview_jinja_variables + [
"trichrome_version=$trichrome_version_code",
"library=libmonochrome.so",
]
}
if (android_64bit_target_cpu) {
jinja_template("trichrome_webview_64_32_manifest") {
input = "java/AndroidManifest.xml"
output = trichrome_webview_64_32_android_manifest
variables = trichrome_jinja_variables + _webview_jinja_variables + [
"use32bitAbi=",
"trichrome_version=$trichrome_64_32_version_code",
"library=libmonochrome_64.so",
]
}
jinja_template("trichrome_webview_32_manifest") {
input = "java/AndroidManifest.xml"
output = trichrome_webview_32_android_manifest
variables = trichrome_jinja_variables + _webview_jinja_variables + [
"trichrome_version=$trichrome_32_version_code",
"library=libmonochrome.so",
]
}
}

View File

@ -0,0 +1,20 @@
# Copyright 2018 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.
import("//build/config/android/rules.gni")
import("//third_party/protobuf/proto_library.gni")
proto_library("aw_variations_seed_proto") {
sources = [ "aw_variations_seed.proto" ]
}
proto_java_library("aw_variations_seed_proto_java") {
proto_path = "."
sources = [ "aw_variations_seed.proto" ]
}
proto_java_library("metrics_bridge_records_proto_java") {
proto_path = "."
sources = [ "metrics_bridge_records.proto" ]
}

View File

@ -0,0 +1,11 @@
# 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.
source_set("public") {
sources = [
"browser/draw_fn.h",
"browser/draw_gl.h",
"browser/draw_sw.h",
]
}

View File

@ -0,0 +1,65 @@
# 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.
source_set("renderer") {
sources = [
"aw_content_renderer_client.cc",
"aw_content_renderer_client.h",
"aw_content_settings_client.cc",
"aw_content_settings_client.h",
"aw_key_systems.cc",
"aw_key_systems.h",
"aw_print_render_frame_helper_delegate.cc",
"aw_print_render_frame_helper_delegate.h",
"aw_render_frame_ext.cc",
"aw_render_frame_ext.h",
"aw_render_thread_observer.cc",
"aw_render_thread_observer.h",
"aw_render_view_ext.cc",
"aw_render_view_ext.h",
"aw_safe_browsing_error_page_controller_delegate_impl.cc",
"aw_safe_browsing_error_page_controller_delegate_impl.h",
"aw_url_loader_throttle_provider.cc",
"aw_url_loader_throttle_provider.h",
"aw_websocket_handshake_throttle_provider.cc",
"aw_websocket_handshake_throttle_provider.h",
"browser_exposed_renderer_interfaces.cc",
"browser_exposed_renderer_interfaces.h",
]
deps = [
"//android_webview:generate_aw_resources",
"//android_webview:generate_aw_strings",
"//android_webview/common",
"//base",
"//components/android_system_error_page",
"//components/autofill/content/renderer",
"//components/cdm/renderer",
"//components/content_capture/common",
"//components/content_capture/renderer",
"//components/js_injection/common",
"//components/js_injection/renderer",
"//components/page_load_metrics/renderer",
"//components/printing/common",
"//components/printing/renderer",
"//components/resources",
"//components/safe_browsing/content/common:interfaces",
"//components/safe_browsing/content/renderer:throttles",
"//components/safe_browsing/core:features",
"//components/safe_browsing/core/common",
"//components/security_interstitials/content/renderer:security_interstitial_page_controller",
"//components/security_interstitials/core",
"//components/security_interstitials/core/common/mojom",
"//components/spellcheck:buildflags",
"//components/spellcheck/renderer",
"//components/strings",
"//components/visitedlink/renderer",
"//content/public/child",
"//content/public/common",
"//content/public/renderer",
"//third_party/blink/public:blink",
"//ui/base",
"//url",
]
}

View File

@ -0,0 +1,42 @@
# Copyright 2018 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.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("support_lib_glue_java") {
sources = [
"java/src/org/chromium/support_lib_glue/IsomorphicAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibJsReplyProxyAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibProxyControllerAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibReflectionUtil.java",
"java/src/org/chromium/support_lib_glue/SupportLibScriptReferenceAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibServiceWorkerClientAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibServiceWorkerControllerAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibServiceWorkerSettingsAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibTracingControllerAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebMessageAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebMessageCallbackAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebMessageListenerAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebMessagePortAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebResourceRequest.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebViewRendererAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebViewRendererClientAdapter.java",
"java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java",
]
deps = [
"//android_webview:browser_java",
"//android_webview/glue:glue_java",
"//android_webview/support_library/boundary_interfaces:boundary_interface_java",
"//android_webview/support_library/callback:callback_java",
"//base:base_java",
"//components/embedder_support/android:util_java",
"//content/public/android:content_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
]
}

View File

@ -0,0 +1,64 @@
# Copyright 2017 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.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("boundary_interface_java") {
sources = [
"src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/IsomorphicObjectBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/JsReplyProxyBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/SafeBrowsingResponseBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/ScriptReferenceBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/ServiceWorkerClientBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/ServiceWorkerControllerBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/ServiceWorkerWebSettingsBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/TracingControllerBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/VisualStateCallbackBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebMessageBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebMessageCallbackBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebMessageListenerBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebMessagePortBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebResourceErrorBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebResourceRequestBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebViewClientBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebViewRendererBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebViewRendererClientBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java",
"src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java",
"src/org/chromium/support_lib_boundary/util/Features.java",
]
proguard_configs = [ "proguard.flags" ]
# Our choice of deps is limited, because boundary_interfaces/ must continue to
# build when we mirror this into AndroidX. We are only permitted to depend on
# core Android classes and other AndroidX classes (must be in the androidx.*
# package name).
deps = [ "//third_party/android_deps:androidx_annotation_annotation_java" ]
}
android_apk("boundary_interface_example_apk") {
apk_name = "BoundaryInterfaceExample"
# Use a dummy android manifest since this code is copied to androidx.
android_manifest = "//build/android/AndroidManifest.xml"
# This is to verify that the boundary interfaces compile and lint correctly
# against the minSdkVersion of the webkit support library module. As the
# minSdkVersion of the support library increases, so should this value. See
# http://crbug.com/828184 for more details.
min_sdk_version = 14
# Explicitly enable lint for this apk.
enable_lint = true
deps = [ ":boundary_interface_java" ]
}

View File

@ -0,0 +1,21 @@
# Copyright 2018 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.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("callback_java") {
sources = [
"java/src/org/chromium/support_lib_callback_glue/SupportLibSafeBrowsingResponse.java",
"java/src/org/chromium/support_lib_callback_glue/SupportLibWebResourceError.java",
"java/src/org/chromium/support_lib_callback_glue/SupportLibWebViewContentsClientAdapter.java",
]
deps = [
"//android_webview:browser_java",
"//android_webview/support_library/boundary_interfaces:boundary_interface_java",
"//base:base_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
]
}

View File

@ -0,0 +1,269 @@
# Copyright 2015 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.
import("//android_webview/variables.gni")
import("//base/android/resource_exclusions.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//build/config/locales.gni")
import("//build/util/version.gni")
import("//chrome/android/trichrome.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//weblayer/variables.gni")
import("//weblayer/weblayer_resource_exclusions.gni")
declare_args() {
# Android package name to use when compiling the system_webview_apk and
# trichrome_webview_apk targets. This should be used if the Android build
# on which you are going to install WebView is configured to load a
# different package name than the default used in AOSP.
system_webview_package_name = "com.android.webview"
# Whether to enable standalone and trichrome WebView bundle build targets.
enable_webview_bundles = true
}
template("system_webview_apk_or_module_tmpl") {
if (!defined(invoker.target_type)) {
_is_bundle_module = false
_target_type = "android_apk"
} else {
_is_bundle_module = invoker.target_type == "android_app_bundle_module"
_target_type = invoker.target_type
}
_exclude_weblayer_java =
defined(invoker.exclude_weblayer_java) && invoker.exclude_weblayer_java
target(_target_type, target_name) {
forward_variables_from(invoker,
"*",
[
"is_64_bit_browser",
"include_32_bit_webview",
"include_64_bit_webview",
])
deps += [
"//android_webview:locale_pak_assets",
"//android_webview:pak_file_assets",
]
if (_exclude_weblayer_java) {
deps += [ "//android_webview:android_webview_no_weblayer_java" ]
} else {
if (_is_bundle_module && weblayer_in_split) {
deps += [
# TODO(crbug.com/1105096): WebLayer resources are added to the base
# module for now because of bugs with shared resources in splits.
":${target_name}__all_weblayer_resources",
"//android_webview:android_webview_no_weblayer_java",
"//weblayer/browser/java:base_module_java",
]
} else {
deps += [ "//android_webview:android_webview_java" ]
}
# Resources from this target will be kept in the base bundle module
# instead of in language splits.
if (!defined(invoker.shared_resources_allowlist_target)) {
shared_resources_allowlist_target =
"//android_webview:system_webview_no_weblayer_apk"
}
}
product_config_java_packages = [ webview_product_config_java_package ]
if (webview_includes_weblayer) {
if (_is_bundle_module) {
deps += [ "//weblayer:bundle_locale_pak_assets" ]
} else {
deps += [ "//weblayer:locale_pak_assets" ]
}
product_config_java_packages += [ weblayer_product_config_java_package ]
}
if (!defined(alternative_android_sdk_dep)) {
alternative_android_sdk_dep = webview_framework_dep
}
if (webview_devui_show_icon) {
deps += [ "//android_webview/nonembedded:devui_launcher_icon_resources" ]
}
_use_trichrome_library =
defined(use_trichrome_library) && use_trichrome_library
assert(
_use_trichrome_library == defined(invoker.static_library_provider),
"If trichrome library is used, static_library_provider must be set " +
"so that a dep can be added on the library APK.")
# Pure 32-bit implies a 32-bit only Webview built on a 64-bit configuration.
_pure_32_bit =
android_64bit_target_cpu && defined(invoker.include_64_bit_webview) &&
!invoker.include_64_bit_webview
not_needed([ "_pure_32_bit" ])
# Flag whether additional deps and libs should be included for each ABI.
_include_primary_support = false
_include_secondary_support = false
if (!_use_trichrome_library) {
shared_resources = true
if (!android_64bit_target_cpu || !_pure_32_bit) {
shared_libraries = [ "//android_webview:libwebviewchromium" ]
_include_primary_support = true
}
if (android_64bit_target_cpu) {
secondary_abi_shared_libraries = [ "//android_webview:libwebviewchromium($android_secondary_abi_toolchain)" ]
_include_secondary_support = true
}
deps += [ "//third_party/icu:icu_assets" ]
} else {
uncompress_shared_libraries = true
app_as_shared_lib = true
# Include placeholder libraries to ensure we are treated as the desired
# architecture.
if (android_64bit_target_cpu) {
if (invoker.is_64_bit_browser) {
native_lib_placeholders = [ "libdummy.so" ]
if (invoker.include_32_bit_webview) {
secondary_abi_shared_libraries = [ "//android_webview:monochrome_64($android_secondary_abi_toolchain)" ]
_include_secondary_support = true
}
} else {
if (invoker.include_64_bit_webview) {
shared_libraries = [ "//android_webview:monochrome" ]
_include_primary_support = true
}
secondary_native_lib_placeholders = [ "libdummy.so" ]
}
} else {
native_lib_placeholders = [ "libdummy.so" ]
}
}
if (_include_primary_support) {
deps += [
"//android_webview:webview_primary_abi_assets",
"//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline",
]
loadable_modules = [ "$root_out_dir/libcrashpad_handler_trampoline.so" ]
if (webview_includes_weblayer) {
deps += [ "//base/android/linker:chromium_android_linker" ]
loadable_modules +=
[ "$root_out_dir/libchromium_android_linker$shlib_extension" ]
}
}
if (_include_secondary_support) {
_trampoline = "//third_party/crashpad/crashpad/handler:crashpad_handler_trampoline($android_secondary_abi_toolchain)"
deps += [
"//android_webview:webview_secondary_abi_assets",
_trampoline,
]
_secondary_out_dir = get_label_info(_trampoline, "root_out_dir")
secondary_abi_loadable_modules =
[ "$_secondary_out_dir/libcrashpad_handler_trampoline.so" ]
if (webview_includes_weblayer) {
deps += [ "//base/android/linker:chromium_android_linker($android_secondary_abi_toolchain)" ]
secondary_abi_loadable_modules +=
[ "$_secondary_out_dir/libchromium_android_linker$shlib_extension" ]
}
}
if (!_use_trichrome_library || android_64bit_target_cpu) {
# 32-bit TrichromeWebView doesn't have a native library, so only do this
# for other configs.
native_lib_version_rule = "//build/util:chrome_version_json"
_native_lib_file =
rebase_path("$root_gen_dir/CHROME_VERSION.json", root_out_dir)
native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)"
}
aapt_locale_allowlist = locales
resource_exclusion_regex = common_resource_exclusion_regex
resource_exclusion_exceptions = common_resource_exclusion_exceptions
if (webview_includes_weblayer) {
resource_values_filter_rules = weblayer_resource_values_filter_rules
resource_exclusion_exceptions += weblayer_resource_exclusion_exceptions
# Note: WebLayer's resource exclusion regex deliberately does not start
# with "|".
resource_exclusion_regex += "|" + weblayer_resource_exclusion_regex
}
if (!_is_bundle_module) {
# Used as an additional apk in test scripts.
never_incremental = true
command_line_flags_file = "webview-command-line"
}
if (!is_java_debug) {
proguard_enabled = true
if (!defined(proguard_configs)) {
proguard_configs = []
}
proguard_configs += [
"//android_webview/nonembedded/java/proguard.flags",
"//base/android/proguard/chromium_apk.flags",
"//base/android/proguard/chromium_code.flags",
]
if (enable_proguard_obfuscation) {
proguard_configs +=
[ "//base/android/proguard/enable_obfuscation.flags" ]
} else {
proguard_configs +=
[ "//base/android/proguard/disable_all_obfuscation.flags" ]
}
png_to_webp = true
}
if (!defined(version_code)) {
if (_use_trichrome_library) {
if (android_64bit_target_cpu) {
if (invoker.is_64_bit_browser) {
if (invoker.include_32_bit_webview) {
version_code = trichrome_64_32_version_code
} else {
version_code = trichrome_64_version_code
}
} else {
if (invoker.include_64_bit_webview) {
version_code = trichrome_32_64_version_code
} else {
version_code = trichrome_32_version_code
}
}
} else {
version_code = trichrome_version_code
}
} else {
if (android_channel == "dev") {
if (_pure_32_bit) {
version_code = webview_32_dev_version_code
} else {
version_code = webview_dev_version_code
}
} else if (android_channel == "beta") {
if (_pure_32_bit) {
version_code = webview_32_beta_version_code
} else {
version_code = webview_beta_version_code
}
} else {
if (_pure_32_bit) {
version_code = webview_32_stable_version_code
} else {
version_code = webview_stable_version_code
}
}
}
}
if (!defined(version_name)) {
version_name = chrome_version_name
}
}
}

View File

@ -0,0 +1,101 @@
# 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.
import("//build/config/android/rules.gni")
import("//build/config/locales.gni")
import("//weblayer/variables.gni")
template("system_webview_bundle") {
_base_target_name = get_label_info(invoker.base_module_target, "name")
_base_target_gen_dir =
get_label_info(invoker.base_module_target, "target_gen_dir")
_base_module_build_config =
"$_base_target_gen_dir/${_base_target_name}.build_config"
_rebased_base_module_build_config =
rebase_path(_base_module_build_config, root_build_dir)
_base_module_version_code =
"@FileArg($_rebased_base_module_build_config:deps_info:version_code)"
if (webview_includes_weblayer && weblayer_in_split) {
# TODO(crbug.com/1105096): If WebView starts using
# //components/module_installer, it will probably make sense to refactor
# chrome_feature_module() to be used here.
_base_module_build_config_target =
"${invoker.base_module_target}$build_config_target_suffix"
_weblayer_module_target = "${target_name}__weblayer_bundle_module"
_weblayer_module_desc = {
name = "weblayer"
module_target = ":${_weblayer_module_target}"
}
# TODO(crbug.com/1105096): This target is needed to add all WebLayer
# resources to the base module because of bugs with shared resources in
# splits.
android_resources("${_base_target_name}__all_weblayer_resources") {
recursive_resource_deps = true
deps = [ "//weblayer/browser/java" ]
if (defined(invoker.weblayer_deps)) {
deps += invoker.weblayer_deps
}
}
android_app_bundle_module(_weblayer_module_target) {
forward_variables_from(invoker,
[
"base_module_target",
"min_sdk_version",
"uncompress_shared_libraries",
])
android_manifest = "//weblayer/browser/java/AndroidManifest.xml"
# The manifest depends on the package name from the base build config.
android_manifest_dep = _base_module_build_config_target
deps = [
"//weblayer/browser/java",
_base_module_build_config_target,
]
if (defined(invoker.weblayer_deps)) {
deps += invoker.weblayer_deps
}
aapt_locale_allowlist = locales
proguard_enabled = !is_java_debug
package_name = "weblayer"
package_id = 126
version_name =
"@FileArg($_rebased_base_module_build_config:deps_info:version_name)"
version_code = _base_module_version_code
manifest_package =
"@FileArg($_rebased_base_module_build_config:deps_info:package_name)"
}
}
android_app_bundle(target_name) {
command_line_flags_file = "webview-command-line"
proguard_enabled = !is_java_debug
enable_language_splits = true
version_code = _base_module_version_code
if (webview_includes_weblayer && weblayer_in_split) {
extra_modules = [ _weblayer_module_desc ]
}
system_image_locale_allowlist = locales
is_multi_abi =
android_64bit_target_cpu && (!defined(invoker.include_64_bit_webview) ||
invoker.include_64_bit_webview) &&
(!defined(invoker.include_32_bit_webview) ||
invoker.include_32_bit_webview)
if (!defined(proguard_android_sdk_dep)) {
proguard_android_sdk_dep = webview_framework_dep
}
# NOTE: Only sign bundle for official builds since this is very slow.
if (enable_chrome_android_internal && use_signing_keys &&
is_official_build) {
sign_bundle = true
keystore_path = webview_keystore_path
keystore_name = webview_keystore_name
keystore_password = webview_keystore_password
}
forward_variables_from(invoker, "*")
}
}

View File

@ -0,0 +1,521 @@
# Copyright 2015 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.
import("//android_webview/variables.gni")
import("//build/config/android/rules.gni")
import("//build/config/python.gni")
import("//device/vr/buildflags/buildflags.gni")
import("//testing/test.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
# Mark all targets as test only.
testonly = true
group("test") {
deps = [
":android_webview_junit_tests",
":android_webview_unittests",
":webview_instrumentation_test_apk",
]
}
python_library("webview_cts_tests") {
pydeps_file = "//android_webview/tools/run_cts.pydeps"
deps = [ "//android_webview:system_webview_apk" ]
data_deps = [
"//build/android:logdog_wrapper_py",
"//build/android:test_runner_py",
"//testing/buildbot/filters:webview_cts_tests_filters",
]
data = [ "//android_webview/tools/cts_config/" ]
}
python_library("system_webview_wpt") {
testonly = true
pydeps_file = "//testing/scripts/run_android_wpt.pydeps"
data_deps = [
"//android_webview:system_webview_apk",
"//android_webview/tools/system_webview_shell:system_webview_shell_layout_test_apk",
"//chrome/test/chromedriver:chromedriver($host_toolchain)",
"//third_party/blink/tools:wpt_tests_android_isolate",
]
}
android_apk("webview_instrumentation_apk") {
# TODO(crbug.com/1099536): Fix tests that break when this is increased.
target_sdk_version = 24
deps = [
":webview_instrumentation_apk_assets",
":webview_instrumentation_apk_resources",
":webview_instrumentation_test_utils_java",
"//android_webview:android_webview_java",
"//android_webview:android_webview_product_config_java",
"//android_webview:common_java",
"//android_webview:locale_pak_assets",
"//android_webview:platform_service_bridge_upstream_implementation_java",
"//base:base_java",
"//base:base_java_test_support",
"//components/embedder_support/android:util_java",
"//components/heap_profiling/multi_process:heap_profiling_java_test_support",
"//components/policy/android:policy_java_test_support",
"//content/public/android:content_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit",
"//ui/android:ui_java",
"//url:gurl_java",
]
apk_name = "WebViewInstrumentation"
android_manifest = "shell/AndroidManifest.xml"
sources = [
"shell/src/org/chromium/android_webview/shell/AwShellActivity.java",
"shell/src/org/chromium/android_webview/shell/AwShellApplication.java",
"shell/src/org/chromium/android_webview/shell/AwShellResourceProvider.java",
"shell/src/org/chromium/android_webview/shell/AwShellSwitches.java",
"shell/src/org/chromium/android_webview/shell/DrawFn.java",
"shell/src/org/chromium/android_webview/test/AwJUnit4ClassRunner.java",
"shell/src/org/chromium/android_webview/test/AwTestContainerView.java",
"shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java",
"shell/src/org/chromium/android_webview/test/NullContentsClient.java",
"shell/src/org/chromium/android_webview/test/OnlyRunIn.java",
"shell/src/org/chromium/android_webview/test/SecondBrowserProcess.java",
"shell/src/org/chromium/android_webview/test/TestContentProvider.java",
]
product_config_java_packages = [ webview_product_config_java_package ]
shared_libraries = [ ":libstandalonelibwebviewchromium" ]
native_lib_version_rule = "//build/util:chrome_version_json"
_native_lib_file =
rebase_path("$root_gen_dir/CHROME_VERSION.json", root_build_dir)
native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)"
command_line_flags_file = "android-webview-command-line"
}
android_resources("webview_instrumentation_apk_resources") {
sources = [
"shell/res/layout/testshell_activity.xml",
"shell/res/raw/resource_file.html",
"shell/res/raw/resource_icon.png",
"shell/res/values/config.xml",
]
}
android_assets("webview_instrumentation_apk_assets") {
deps = [
"//android_webview:pak_file_assets",
"//third_party/icu:icu_assets",
]
sources = [
"shell/assets/asset_file.html",
"shell/assets/asset_icon.png",
"shell/assets/autofill.html",
"shell/assets/cookie_test.html",
"shell/assets/cors.html",
"shell/assets/full_screen_video.js",
"shell/assets/full_screen_video_inside_div_test.html",
"shell/assets/full_screen_video_test.html",
"shell/assets/full_screen_video_test_not_preloaded.html",
"shell/assets/key-system-test.html",
"shell/assets/star.svg",
"shell/assets/star.svgz",
"shell/assets/video.webm",
"shell/assets/visual_state_during_fullscreen_test.html",
"shell/assets/visual_state_on_page_commit_visible_test.html",
"shell/assets/visual_state_waits_for_js_detached_test.html",
"shell/assets/visual_state_waits_for_js_test.html",
]
if (use_v8_context_snapshot) {
deps += [ "//tools/v8_context_snapshot:v8_context_snapshot_assets" ]
} else {
deps += [ "//v8:v8_external_startup_data_assets" ]
}
}
shared_library("libstandalonelibwebviewchromium") {
testonly = true
sources = [ "shell/src/draw_gl/draw_fn.cc" ]
ldflags = [ "-Wl,-shared,-Bsymbolic" ]
deps = [
":webview_instrumentation_test_native_jni_impl",
"//android_webview/lib",
"//android_webview/lib:webview_entry_point",
"//android_webview/nonembedded",
"//android_webview/public",
"//base",
"//components/heap_profiling/multi_process:test_support",
"//content/public/test/android:content_native_test_support",
]
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
configs += [ "//build/config/android:hide_all_but_jni" ]
}
instrumentation_test_apk("webview_instrumentation_test_apk") {
apk_name = "WebViewInstrumentationTest"
apk_under_test = ":webview_instrumentation_apk"
android_manifest = "../javatests/AndroidManifest.xml"
min_sdk_version = 21
deps = [
":webview_instrumentation_test_utils_java",
"//android_webview:android_webview_java",
"//android_webview:common_aidl_java",
"//android_webview:common_crash_java",
"//android_webview:common_platform_services_java",
"//android_webview:common_variations_java",
"//android_webview/nonembedded:devui_java",
"//android_webview/nonembedded:services_java",
"//android_webview/proto:aw_variations_seed_proto_java",
"//android_webview/proto:metrics_bridge_records_proto_java",
"//android_webview/test/embedded_test_server:aw_net_java_test_support",
"//base:base_java",
"//base:base_java_test_support",
"//components/autofill/android:autofill_java",
"//components/autofill/android/provider:java",
"//components/autofill/core/common/mojom:mojo_types_java",
"//components/background_task_scheduler:background_task_scheduler_task_ids_java",
"//components/content_capture/android:java",
"//components/embedder_support/android:util_java",
"//components/embedder_support/android:web_contents_delegate_java",
"//components/heap_profiling/multi_process:heap_profiling_java_test_support",
"//components/metrics:metrics_java",
"//components/minidump_uploader:minidump_uploader_java",
"//components/minidump_uploader:minidump_uploader_javatests",
"//components/policy/android:policy_java",
"//components/policy/android:policy_java_test_support",
"//components/safe_browsing/android:safe_browsing_java",
"//components/variations/android:variations_java",
"//components/variations/proto:proto_java",
"//components/version_info/android:version_constants_java",
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//mojo/public/java:bindings_java",
"//net/android:net_java",
"//net/android:net_java_test_support",
"//net/android:net_javatests",
"//services/device/public/java:geolocation_java",
"//services/device/public/java:geolocation_java_test_support",
"//third_party/android_deps:androidx_activity_activity_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_core_core_java",
"//third_party/android_deps:androidx_fragment_fragment_java",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_deps:com_google_code_findbugs_jsr305_java",
"//third_party/android_deps:com_google_guava_failureaccess_java",
"//third_party/android_deps:espresso_java",
"//third_party/android_deps:protobuf_lite_runtime_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/blink/public/mojom:web_feature_mojo_bindings_java",
"//third_party/guava:guava_android_java",
"//third_party/hamcrest:hamcrest_java",
"//third_party/junit",
"//third_party/metrics_proto:metrics_proto_java",
"//third_party/mockito:mockito_java",
"//ui/android:ui_java",
"//ui/android:ui_java_test_support",
"//url:gurl_java",
]
sources = [
"../javatests/src/org/chromium/android_webview/test/AcceptLanguageTest.java",
"../javatests/src/org/chromium/android_webview/test/AndroidProtocolHandlerTest.java",
"../javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java",
"../javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java",
"../javatests/src/org/chromium/android_webview/test/ArchiveTest.java",
"../javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java",
"../javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java",
"../javatests/src/org/chromium/android_webview/test/AwAutofillTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentCaptureTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientAutoLoginTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientFaviconTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientGetDefaultVideoPosterTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientOnRendererUnresponsiveTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientOnUnhandledKeyEventTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsClientVisitedHistoryTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsContainerViewTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsLifecycleNotifierTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java",
"../javatests/src/org/chromium/android_webview/test/AwContentsTest.java",
"../javatests/src/org/chromium/android_webview/test/AwFormDatabaseTest.java",
"../javatests/src/org/chromium/android_webview/test/AwImeTest.java",
"../javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java",
"../javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java",
"../javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java",
"../javatests/src/org/chromium/android_webview/test/AwNetworkConfigurationTest.java",
"../javatests/src/org/chromium/android_webview/test/AwPageLoadMetricsTest.java",
"../javatests/src/org/chromium/android_webview/test/AwPermissionManagerTest.java",
"../javatests/src/org/chromium/android_webview/test/AwProxyControllerTest.java",
"../javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java",
"../javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java",
"../javatests/src/org/chromium/android_webview/test/AwServiceWorkerClientTest.java",
"../javatests/src/org/chromium/android_webview/test/AwSettingsTest.java",
"../javatests/src/org/chromium/android_webview/test/AwUncaughtExceptionTest.java",
"../javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java",
"../javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java",
"../javatests/src/org/chromium/android_webview/test/AwZoomTest.java",
"../javatests/src/org/chromium/android_webview/test/CleanupReferenceTest.java",
"../javatests/src/org/chromium/android_webview/test/ClearHistoryTest.java",
"../javatests/src/org/chromium/android_webview/test/ClientAddMessageToConsoleTest.java",
"../javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java",
"../javatests/src/org/chromium/android_webview/test/ClientOnPageStartedTest.java",
"../javatests/src/org/chromium/android_webview/test/ClientOnReceivedError2Test.java",
"../javatests/src/org/chromium/android_webview/test/ClientOnReceivedErrorTest.java",
"../javatests/src/org/chromium/android_webview/test/ClientOnReceivedHttpErrorTest.java",
"../javatests/src/org/chromium/android_webview/test/ConsoleMessagesForBlockedLoadsTest.java",
"../javatests/src/org/chromium/android_webview/test/ContentViewMiscTest.java",
"../javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java",
"../javatests/src/org/chromium/android_webview/test/CookieManagerTest.java",
"../javatests/src/org/chromium/android_webview/test/DarkModeTest.java",
"../javatests/src/org/chromium/android_webview/test/DisableHardwareAccelerationForTest.java",
"../javatests/src/org/chromium/android_webview/test/FullScreenVideoTestAwContentsClient.java",
"../javatests/src/org/chromium/android_webview/test/GeolocationTest.java",
"../javatests/src/org/chromium/android_webview/test/GetTitleTest.java",
"../javatests/src/org/chromium/android_webview/test/HeapProfilingTest.java",
"../javatests/src/org/chromium/android_webview/test/HttpAuthDatabaseTest.java",
"../javatests/src/org/chromium/android_webview/test/JsJavaInteractionTest.java",
"../javatests/src/org/chromium/android_webview/test/KeySystemTest.java",
"../javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java",
"../javatests/src/org/chromium/android_webview/test/LoadUrlTest.java",
"../javatests/src/org/chromium/android_webview/test/MediaAccessPermissionRequestTest.java",
"../javatests/src/org/chromium/android_webview/test/MemoryMetricsLoggerTest.java",
"../javatests/src/org/chromium/android_webview/test/NavigationHistoryTest.java",
"../javatests/src/org/chromium/android_webview/test/OnDiskFileTest.java",
"../javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java",
"../javatests/src/org/chromium/android_webview/test/PopupWindowTest.java",
"../javatests/src/org/chromium/android_webview/test/PostMessageTest.java",
"../javatests/src/org/chromium/android_webview/test/RenderProcessGoneHelper.java",
"../javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java",
"../javatests/src/org/chromium/android_webview/test/SaveRestoreStateTest.java",
"../javatests/src/org/chromium/android_webview/test/SslPreferencesTest.java",
"../javatests/src/org/chromium/android_webview/test/StandaloneAwQuotaManagerBridgeTest.java",
"../javatests/src/org/chromium/android_webview/test/TestAwContents.java",
"../javatests/src/org/chromium/android_webview/test/TestAwContentsClient.java",
"../javatests/src/org/chromium/android_webview/test/TestAwServiceWorkerClient.java",
"../javatests/src/org/chromium/android_webview/test/UserAgentTest.java",
"../javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java",
"../javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java",
"../javatests/src/org/chromium/android_webview/test/VariationsTest.java",
"../javatests/src/org/chromium/android_webview/test/VisualStateTest.java",
"../javatests/src/org/chromium/android_webview/test/WebKitHitTestTest.java",
"../javatests/src/org/chromium/android_webview/test/WebViewAsynchronousFindApisTest.java",
"../javatests/src/org/chromium/android_webview/test/WebViewFindApisTestRule.java",
"../javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java",
"../javatests/src/org/chromium/android_webview/test/common/crash/CrashInfoEqualityMatcher.java",
"../javatests/src/org/chromium/android_webview/test/common/crash/CrashInfoTest.java",
"../javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/AwNonembeddedUmaRecorderTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/CrashesListFragmentTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/DeveloperUiTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/DeveloperUiTestUtils.java",
"../javatests/src/org/chromium/android_webview/test/devui/FlagsFragmentTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/HomeFragmentTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/util/CrashBugUrlFactoryTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/util/UnuploadedFilesStateLoaderTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/util/UploadedCrashesInfoLoaderTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashInfoCollectorTest.java",
"../javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashLogParserTest.java",
"../javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java",
"../javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java",
"../javatests/src/org/chromium/android_webview/test/services/MinidumpUploadJobTest.java",
"../javatests/src/org/chromium/android_webview/test/services/MockMetricsBridgeService.java",
"../javatests/src/org/chromium/android_webview/test/services/MockVariationsSeedServer.java",
"../javatests/src/org/chromium/android_webview/test/services/ServiceConnectionHelper.java",
"../javatests/src/org/chromium/android_webview/test/services/VariationsSeedServerTest.java",
"../javatests/src/org/chromium/android_webview/test/services/VisualStateCallbackTest.java",
"../javatests/src/org/chromium/android_webview/test/util/AwQuotaManagerBridgeTestUtil.java",
"../javatests/src/org/chromium/android_webview/test/util/AwTestTouchUtils.java",
"../javatests/src/org/chromium/android_webview/test/util/CommonResources.java",
"../javatests/src/org/chromium/android_webview/test/util/CookieUtils.java",
"../javatests/src/org/chromium/android_webview/test/util/GraphicsTestUtils.java",
"../javatests/src/org/chromium/android_webview/test/util/ImagePageGenerator.java",
"../javatests/src/org/chromium/android_webview/test/util/JSUtils.java",
"../javatests/src/org/chromium/android_webview/test/util/JavascriptEventObserver.java",
"../javatests/src/org/chromium/android_webview/test/util/VideoSurfaceViewUtils.java",
"../javatests/src/org/chromium/android_webview/test/util/VideoTestUtil.java",
"../javatests/src/org/chromium/android_webview/test/util/VideoTestWebServer.java",
]
if (!use_jacoco_coverage) {
# Jacoco requires strict mode to be turned off since it writes coverage data to files.
sources += [ "../javatests/src/org/chromium/android_webview/test/AwStrictModeTest.java" ]
}
data = [ "data/" ]
data_deps =
[ "//testing/buildbot/filters:webview_instrumentation_test_apk_filters" ]
if (enable_chrome_android_internal) {
data_deps +=
[ "//clank/build/bot/filters:webview_instrumentation_test_apk_filters" ]
}
# We only want to bother including these on bots set up for VR testing
if (include_vr_data) {
data += [
"//chrome/android/shared_preference_files/test/",
"//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk",
]
}
additional_apks = [
"//android_webview/test/embedded_test_server:aw_net_test_support_apk",
"//net/android:net_test_support_apk",
]
}
android_library("webview_instrumentation_test_utils_java") {
testonly = true
sources = [
"../javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java",
"shell/src/org/chromium/android_webview/test/util/MemoryMetricsLoggerUtils.java",
]
deps = [
"//android_webview:common_variations_java",
"//base:base_java",
"//base:jni_java",
"//components/variations/android:variations_java",
"//third_party/junit",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
generate_jni("webview_instrumentation_test_native_jni") {
testonly = true
sources = [
"../javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java",
"shell/src/org/chromium/android_webview/test/util/MemoryMetricsLoggerUtils.java",
]
}
source_set("webview_instrumentation_test_native_jni_impl") {
sources = [
"browser/variations_test_utils.cc",
"shell/memory_metrics_logger_utils.cc",
]
deps = [
":webview_instrumentation_test_native_jni",
"//android_webview/browser",
"//base",
"//base/test:test_support",
"//components/embedder_support/android/metrics",
"//third_party/protobuf:protobuf_lite",
]
}
test("android_webview_unittests") {
deps = [
":android_webview_unittests_assets",
":android_webview_unittests_java",
":android_webview_unittests_jni",
"//android_webview/browser",
"//android_webview/browser/gfx",
"//android_webview/browser/lifecycle",
"//android_webview/browser/metrics",
"//android_webview/common",
"//base/test:test_support",
"//components/autofill/core/browser",
"//components/embedder_support/android:util",
"//components/metrics",
"//components/prefs:prefs",
"//components/prefs:test_support",
"//content:content",
"//content/test:test_support",
"//mojo/core/embedder",
"//net:net",
"//net:test_support",
"//services/network:test_support",
"//ui/base:ui_base_jni_headers",
"//ui/gl",
"//ui/gl:test_support",
]
sources = [
"../browser/aw_browser_context_unittest.cc",
"../browser/aw_content_browser_client_unittest.cc",
"../browser/aw_contents_client_bridge_unittest.cc",
"../browser/aw_form_database_service_unittest.cc",
"../browser/aw_media_url_interceptor_unittest.cc",
"../browser/aw_pac_processor_unittest.cc",
"../browser/aw_permission_manager_unittest.cc",
"../browser/gfx/aw_attaching_to_window_recorder_unittest.cc",
"../browser/gfx/begin_frame_source_webview_unittest.cc",
"../browser/gfx/browser_view_renderer_unittest.cc",
"../browser/gfx/test/fake_window.cc",
"../browser/gfx/test/fake_window.h",
"../browser/gfx/test/rendering_test.cc",
"../browser/gfx/test/rendering_test.h",
"../browser/lifecycle/aw_contents_lifecycle_notifier_unittest.cc",
"../browser/metrics/aw_stability_metrics_provider_unittest.cc",
"../browser/metrics/visibility_metrics_logger_unittest.cc",
"../browser/permission/media_access_permission_request_unittest.cc",
"../browser/permission/permission_request_handler_unittest.cc",
"../browser/renderer_host/auto_login_parser_unittest.cc",
"../browser/safe_browsing/aw_safe_browsing_allowlist_manager_unittest.cc",
"../browser/scoped_add_feature_flags_unittests.cc",
"../browser/state_serializer_unittest.cc",
"../lib/webview_tests.cc",
]
deps += [ "//v8:v8_external_startup_data_assets" ]
}
android_assets("android_webview_unittests_assets") {
sources = [ "unittest/assets/asset_file.ogg" ]
}
android_library("android_webview_unittests_java") {
testonly = true
deps = [
"//android_webview:android_webview_java",
"//base:base_java",
"//content/public/test/android:content_java_test_support",
]
sources = [ "../unittestjava/src/org/chromium/android_webview/unittest/MockAwContentsClientBridge.java" ]
}
generate_jni("android_webview_unittests_jni") {
testonly = true
sources = [ "../unittestjava/src/org/chromium/android_webview/unittest/MockAwContentsClientBridge.java" ]
}
# robolectric tests
junit_binary("android_webview_junit_tests") {
sources = [
"../junit/src/org/chromium/android_webview/robolectric/AwDisplayCutoutControllerTest.java",
"../junit/src/org/chromium/android_webview/robolectric/AwLayoutSizerTest.java",
"../junit/src/org/chromium/android_webview/robolectric/AwScrollOffsetManagerTest.java",
"../junit/src/org/chromium/android_webview/robolectric/FindAddressTest.java",
"../junit/src/org/chromium/android_webview/robolectric/common/FlagOverrideHelperTest.java",
"../junit/src/org/chromium/android_webview/robolectric/common/services/ServiceNamesTest.java",
"../junit/src/org/chromium/android_webview/robolectric/metrics/AwNonembeddedUmaReplayerTest.java",
]
deps = [
"//android_webview:android_webview_java",
"//android_webview/nonembedded:services_java",
"//android_webview/proto:metrics_bridge_records_proto_java",
"//base:base_java",
"//base:base_java_test_support",
"//base:base_junit_test_support",
"//content/public/test/android:content_java_test_support",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_deps:protobuf_lite_runtime_java",
"//third_party/android_support_test_runner:runner_java",
]
package_name = "org.chromium.android_webview.robolectric"
}

View File

@ -0,0 +1,74 @@
# Copyright 2017 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.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("aw_net_java_test_support") {
testonly = true
sources = [
"java/src/org/chromium/android_webview/test/AwEmbeddedTestServer.java",
"java/src/org/chromium/android_webview/test/AwEmbeddedTestServerImpl.java",
"java/src/org/chromium/android_webview/test/AwEmbeddedTestServerService.java",
]
deps = [
"//base:base_java",
"//base:base_java_test_support",
"//net/android:embedded_test_server_aidl_java",
"//net/android:net_java",
"//net/android:net_java_test_support",
"//net/android:net_java_test_support_provider",
]
}
generate_jni("aw_net_jni_headers") {
testonly = true
sources = [
"java/src/org/chromium/android_webview/test/AwEmbeddedTestServerImpl.java",
]
}
source_set("aw_java_test_native_support") {
testonly = true
sources = [
"../../../net/test/embedded_test_server/android/embedded_test_server_android.cc",
"../../../net/test/embedded_test_server/android/embedded_test_server_android.h",
"aw_embedded_test_server.cc",
"aw_test_entry_point.cc",
]
deps = [ "//net:test_support" ]
public_deps = [
":aw_net_jni_headers",
"//net:net_test_jni_headers",
]
}
shared_library("aw_net_java_test_native_support") {
testonly = true
deps = [
":aw_java_test_native_support",
"//net:test_support",
]
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
configs += [ "//build/config/android:hide_all_but_jni" ]
}
android_apk("aw_net_test_support_apk") {
testonly = true
# Used as an additional_apk in test scripts.
never_incremental = true
# Multidex requires a custom Application class to initialize it. Simpler to
# just disable it.
enable_multidex = false
deps = [
":aw_net_java_test_support",
"//base:base_java",
]
android_manifest = "java/AndroidManifest.xml"
apk_name = "ChromiumNetTestAwSupport"
shared_libraries = [ ":aw_net_java_test_native_support" ]
}

View File

@ -0,0 +1,73 @@
# Copyright 2016 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.
import("//build/config/android/rules.gni")
import("//testing/test.gni")
group("webview_ui_test_app") {
testonly = true
deps = [
":webview_ui_test_app_apk",
":webview_ui_test_app_test_apk",
]
}
android_apk("webview_ui_test_app_apk") {
apk_name = "WebViewUiTestApp"
android_manifest = "java/AndroidManifest.xml"
deps = [
":webview_ui_test_app_apk_resources",
":webview_ui_test_app_java",
]
}
android_library("webview_ui_test_app_java") {
sources =
[ "java/src/org/chromium/webview_ui_test/WebViewUiTestActivity.java" ]
deps = [
":webview_ui_test_app_apk_resources",
"//base:base_java",
]
}
android_resources("webview_ui_test_app_apk_resources") {
sources = [
"java/res/layout/edittext_webview.xml",
"java/res/layout/fullscreen_webview.xml",
"java/res/values/strings.xml",
]
}
instrumentation_test_apk("webview_ui_test_app_test_apk") {
apk_name = "WebViewUiTestAppTest"
apk_under_test = ":webview_ui_test_app_apk"
android_manifest = "javatests/AndroidManifest.xml"
sources = [
"javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java",
"javatests/src/org/chromium/webview_ui_test/test/DropDownListTest.java",
"javatests/src/org/chromium/webview_ui_test/test/WebViewJSTest.java",
"javatests/src/org/chromium/webview_ui_test/test/util/Actions.java",
"javatests/src/org/chromium/webview_ui_test/test/util/Atoms.java",
"javatests/src/org/chromium/webview_ui_test/test/util/UseLayout.java",
"javatests/src/org/chromium/webview_ui_test/test/util/WebViewSyncWrapper.java",
"javatests/src/org/chromium/webview_ui_test/test/util/WebViewUiTestRule.java",
]
deps = [
":webview_ui_test_app_apk_resources",
":webview_ui_test_app_java",
"//base:base_java",
"//base:base_java_test_support",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_deps:espresso_java",
"//third_party/android_sdk:android_test_base_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/hamcrest:hamcrest_java",
"//third_party/junit",
"//third_party/ub-uiautomator:ub_uiautomator_java",
]
data = [ "test/data/" ]
use_webview_provider = system_webview_apk_target
}

View File

@ -0,0 +1,77 @@
# Generated by running:
# build/print_python_deps.py --output android_webview/tools/run_cts.pydeps --gn-paths android_webview/tools/run_cts.py
//android_webview/tools/run_cts.py
//build/android/devil_chromium.py
//build/android/pylib/__init__.py
//build/android/pylib/constants/__init__.py
//build/android/pylib/constants/host_paths.py
//build/android/pylib/local/__init__.py
//build/android/pylib/local/emulator/__init__.py
//build/android/pylib/local/emulator/avd.py
//build/android/pylib/local/emulator/ini.py
//build/android/pylib/local/emulator/proto/__init__.py
//build/android/pylib/local/emulator/proto/avd_pb2.py
//build/android/pylib/utils/__init__.py
//build/android/pylib/utils/test_filter.py
//third_party/catapult/common/py_utils/py_utils/__init__.py
//third_party/catapult/common/py_utils/py_utils/cloud_storage.py
//third_party/catapult/common/py_utils/py_utils/cloud_storage_global_lock.py
//third_party/catapult/common/py_utils/py_utils/lock.py
//third_party/catapult/common/py_utils/py_utils/tempfile_ext.py
//third_party/catapult/dependency_manager/dependency_manager/__init__.py
//third_party/catapult/dependency_manager/dependency_manager/archive_info.py
//third_party/catapult/dependency_manager/dependency_manager/base_config.py
//third_party/catapult/dependency_manager/dependency_manager/cloud_storage_info.py
//third_party/catapult/dependency_manager/dependency_manager/dependency_info.py
//third_party/catapult/dependency_manager/dependency_manager/dependency_manager_util.py
//third_party/catapult/dependency_manager/dependency_manager/exceptions.py
//third_party/catapult/dependency_manager/dependency_manager/local_path_info.py
//third_party/catapult/dependency_manager/dependency_manager/manager.py
//third_party/catapult/dependency_manager/dependency_manager/uploader.py
//third_party/catapult/devil/devil/__init__.py
//third_party/catapult/devil/devil/android/__init__.py
//third_party/catapult/devil/devil/android/apk_helper.py
//third_party/catapult/devil/devil/android/constants/__init__.py
//third_party/catapult/devil/devil/android/constants/chrome.py
//third_party/catapult/devil/devil/android/constants/file_system.py
//third_party/catapult/devil/devil/android/decorators.py
//third_party/catapult/devil/devil/android/device_denylist.py
//third_party/catapult/devil/devil/android/device_errors.py
//third_party/catapult/devil/devil/android/device_signal.py
//third_party/catapult/devil/devil/android/device_temp_file.py
//third_party/catapult/devil/devil/android/device_utils.py
//third_party/catapult/devil/devil/android/install_commands.py
//third_party/catapult/devil/devil/android/logcat_monitor.py
//third_party/catapult/devil/devil/android/md5sum.py
//third_party/catapult/devil/devil/android/ndk/__init__.py
//third_party/catapult/devil/devil/android/ndk/abis.py
//third_party/catapult/devil/devil/android/sdk/__init__.py
//third_party/catapult/devil/devil/android/sdk/aapt.py
//third_party/catapult/devil/devil/android/sdk/adb_wrapper.py
//third_party/catapult/devil/devil/android/sdk/build_tools.py
//third_party/catapult/devil/devil/android/sdk/bundletool.py
//third_party/catapult/devil/devil/android/sdk/intent.py
//third_party/catapult/devil/devil/android/sdk/keyevent.py
//third_party/catapult/devil/devil/android/sdk/split_select.py
//third_party/catapult/devil/devil/android/sdk/version_codes.py
//third_party/catapult/devil/devil/android/tools/__init__.py
//third_party/catapult/devil/devil/android/tools/script_common.py
//third_party/catapult/devil/devil/base_error.py
//third_party/catapult/devil/devil/constants/__init__.py
//third_party/catapult/devil/devil/constants/exit_codes.py
//third_party/catapult/devil/devil/devil_env.py
//third_party/catapult/devil/devil/utils/__init__.py
//third_party/catapult/devil/devil/utils/cmd_helper.py
//third_party/catapult/devil/devil/utils/host_utils.py
//third_party/catapult/devil/devil/utils/lazy/__init__.py
//third_party/catapult/devil/devil/utils/lazy/weak_constant.py
//third_party/catapult/devil/devil/utils/logging_common.py
//third_party/catapult/devil/devil/utils/lsusb.py
//third_party/catapult/devil/devil/utils/parallelizer.py
//third_party/catapult/devil/devil/utils/reraiser_thread.py
//third_party/catapult/devil/devil/utils/reset_usb.py
//third_party/catapult/devil/devil/utils/run_tests_helper.py
//third_party/catapult/devil/devil/utils/timeout_retry.py
//third_party/catapult/devil/devil/utils/watchdog_timer.py
//third_party/catapult/devil/devil/utils/zip_utils.py
//third_party/catapult/third_party/zipfile/zipfile_2_7_13.py

View File

@ -0,0 +1,150 @@
# Copyright 2015 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.
import("//build/config/android/rules.gni")
import("//testing/test.gni")
# Mark all targets as test only.
testonly = true
group("system_webview_shell") {
deps = [
":system_webview_shell_apk",
":system_webview_shell_layout_test_apk",
":system_webview_shell_page_cycler_apk",
]
}
declare_args() {
# Android package name to use for system_webview_shell_apk (the WebView shell
# browser). You can change this package name to work around signing key
# conflicts (INSTALL_FAILED_UPDATE_INCOMPATIBLE) on devices/emulators which
# have the shell browser preinstalled under the default package name.
system_webview_shell_package_name = "org.chromium.webview_shell"
}
system_webview_shell_android_manifest =
"$root_gen_dir/android_webview/system_webview_shell_apk/AndroidManifest.xml"
android_apk("system_webview_shell_apk") {
apk_name = "SystemWebViewShell"
android_manifest = system_webview_shell_android_manifest
android_manifest_dep = ":system_webview_shell_manifest"
deps = [
":system_webview_shell_apk_java",
":system_webview_shell_apk_resources",
]
}
android_library("system_webview_shell_apk_java") {
testonly = true
sources = [
"apk/src/org/chromium/webview_shell/JankActivity.java",
"apk/src/org/chromium/webview_shell/PageCyclerTestActivity.java",
"apk/src/org/chromium/webview_shell/StartupTimeActivity.java",
"apk/src/org/chromium/webview_shell/TelemetryActivity.java",
"apk/src/org/chromium/webview_shell/TelemetryMemoryPressureActivity.java",
"apk/src/org/chromium/webview_shell/WebPlatformTestsActivity.java",
"apk/src/org/chromium/webview_shell/WebViewAnimationTestActivity.java",
"apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java",
"apk/src/org/chromium/webview_shell/WebViewBrowserSecondProcessActivity.java",
"apk/src/org/chromium/webview_shell/WebViewCreateDestroyActivity.java",
"apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java",
"apk/src/org/chromium/webview_shell/WebViewPackageHelper.java",
"apk/src/org/chromium/webview_shell/WebViewThreadTestActivity.java",
"apk/src/org/chromium/webview_shell/WebViewTracingActivity.java",
"apk/src/org/chromium/webview_shell/WebViewWithClipPath.java",
]
deps = [
":system_webview_shell_apk_resources",
"//base:base_java",
"//third_party/android_deps:android_support_v7_appcompat_java",
"//third_party/android_deps:androidx_activity_activity_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_savedstate_savedstate_java",
"//third_party/android_deps:androidx_webkit_webkit_java",
"//third_party/guava:guava_android_java",
]
resources_package = "org.chromium.webview_shell"
}
jinja_template("system_webview_shell_manifest") {
input = "apk/AndroidManifest.xml"
output = system_webview_shell_android_manifest
variables = [ "manifest_package=$system_webview_shell_package_name" ]
}
android_resources("system_webview_shell_apk_resources") {
sources = [
"apk/res/drawable-mdpi/breadcrumb_arrow_black.png",
"apk/res/drawable-mdpi/ic_launcher.png",
"apk/res/layout/activity_empty.xml",
"apk/res/layout/activity_web_platform_tests.xml",
"apk/res/layout/activity_web_platform_tests_child.xml",
"apk/res/layout/activity_webview.xml",
"apk/res/layout/activity_webview_animation_test.xml",
"apk/res/layout/activity_webview_browser.xml",
"apk/res/menu/main_menu.xml",
"apk/res/values-night/colors.xml",
"apk/res/values-v17/styles.xml",
"apk/res/values-v29/styles.xml",
"apk/res/values/colors.xml",
"apk/res/values/strings.xml",
"apk/res/values/styles.xml",
"apk/res/xml/network_security_config.xml",
]
deps = [ "//third_party/android_deps:android_support_v7_appcompat_java" ]
}
instrumentation_test_apk("system_webview_shell_page_cycler_apk") {
apk_name = "SystemWebViewShellPageCycler"
apk_under_test = ":system_webview_shell_apk"
android_manifest = "page_cycler/AndroidManifest.xml"
sources = [ "page_cycler/src/org/chromium/webview_shell/page_cycler/PageCyclerTest.java" ]
deps = [
":system_webview_shell_apk_java",
"//base:base_java",
"//base:base_java_test_support",
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//testing/android/reporter:reporter_java",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit",
]
}
instrumentation_test_apk("system_webview_shell_layout_test_apk") {
apk_name = "SystemWebViewShellLayoutTest"
apk_under_test = ":system_webview_shell_apk"
android_manifest = "layout_tests/AndroidManifest.xml"
sources = [
"layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java",
"layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java",
"layout_tests/src/org/chromium/webview_shell/test/WebViewThreadTest.java",
]
deps = [
":system_webview_shell_apk_java",
"//base:base_java",
"//base:base_java_test_support",
"//testing/android/reporter:reporter_java",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_sdk:android_test_base_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit",
]
data = [
"test/data/",
"//third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/",
"//third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/",
"//third_party/blink/web_tests/platform/win/virtual/stable/webexposed/",
"//third_party/blink/web_tests/resources/global-interface-listing.js",
"//third_party/blink/web_tests/virtual/stable/webexposed/",
"//third_party/blink/web_tests/webexposed/global-interface-listing.html",
"//third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt",
]
use_webview_provider = system_webview_apk_target
}

View File

@ -0,0 +1,37 @@
# Copyright 2018 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.
import("//build/config/android/channel.gni")
import("//build/config/android/config.gni")
import("//weblayer/variables.gni")
declare_args() {
# Show a launcher icon to open WebView developer UI. This is enabled by
# default for all prestable builds. The icon for Monochrome is shown
# dynamically at runtime if Monochrome is the current selected system WebView
# implementation or hidden otherwise.
webview_devui_show_icon = android_channel != "stable"
}
system_webview_android_manifest =
"$root_gen_dir/android_webview/system_webview_apk/AndroidManifest.xml"
trichrome_webview_android_manifest =
"$root_gen_dir/android_webview/trichrome_webview_apk/AndroidManifest.xml"
trichrome_webview_64_32_android_manifest = "$root_gen_dir/android_webview/trichrome_webview_64_32_apk/AndroidManifest.xml"
trichrome_webview_32_android_manifest =
"$root_gen_dir/android_webview/trichrome_webview_32_apk/AndroidManifest.xml"
upstream_only_webview_deps = [
"//android_webview:platform_service_bridge_upstream_implementation_java",
"//android_webview/nonembedded:icon_resources",
]
if (webview_includes_weblayer) {
upstream_only_webview_deps +=
[ "//weblayer/browser/java:gms_bridge_upstream_impl_java" ]
}
webview_jinja_variables = [ "use_isolated_splits=$weblayer_in_split" ]
webview_product_config_java_package = "org.chromium.android_webview"

View File

@ -0,0 +1,35 @@
# Copyright 2015 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.
import("//tools/grit/repack.gni")
import("webview_repack_locales_list.gni")
# Wraps repack_locales(), setting the source_patterns and deps required for
# Chrome.
template("webview_repack_locales") {
repack_locales(target_name) {
forward_variables_from(invoker, "*")
if (!defined(deps)) {
deps = []
}
# Adding webview specific pak file? You should add it to
# webview_repack_locales_source_patterns, so it is also included in
# Monochrome.
source_patterns = [
"${root_gen_dir}/android_webview/components_strings_",
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
"${root_gen_dir}/ui/strings/app_locale_settings_",
]
deps += [
"//android_webview:generate_components_strings",
"//third_party/blink/public/strings",
"//ui/strings:app_locale_settings",
]
source_patterns += webview_repack_locales_source_patterns
deps += webview_repack_locales_deps
output_dir = "$root_out_dir/android_webview/locales"
}
}

View File

@ -0,0 +1,10 @@
# Copyright 2016 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.
# For how to add pattern, see additional_source_patterns argument of
# _repack_one_locale in chrome/chrome_repack_locales.gni.
webview_repack_locales_source_patterns =
[ "${root_gen_dir}/android_webview/aw_strings_" ]
webview_repack_locales_deps = [ "//android_webview:generate_aw_strings" ]

65
src/apps/BUILD.gn Normal file
View File

@ -0,0 +1,65 @@
# Copyright 2014 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.
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//extensions/buildflags/buildflags.gni")
assert(!is_android && !is_ios)
assert(enable_extensions,
"Cannot depend on extensions because enable_extensions=false.")
static_library("apps") {
sources = []
sources += [
"app_lifetime_monitor.cc",
"app_lifetime_monitor.h",
"app_lifetime_monitor_factory.cc",
"app_lifetime_monitor_factory.h",
"app_restore_service.cc",
"app_restore_service.h",
"app_restore_service_factory.cc",
"app_restore_service_factory.h",
"browser_context_keyed_service_factories.cc",
"browser_context_keyed_service_factories.h",
"launcher.cc",
"launcher.h",
"saved_files_service.cc",
"saved_files_service.h",
"saved_files_service_factory.cc",
"saved_files_service_factory.h",
"switches.cc",
"switches.h",
]
configs += [ "//build/config/compiler:wexit_time_destructors" ]
deps = [
"//base/util/values:values_util",
"//components/keyed_service/content",
"//content/public/browser",
"//content/public/common",
"//extensions/browser",
"//extensions/common",
"//extensions/common/api",
]
if (is_chromeos) {
deps += [ "//components/user_manager" ]
}
}
static_library("test_support") {
testonly = true
sources = [
"test/app_window_waiter.cc",
"test/app_window_waiter.h",
]
public_deps = [
"//content/public/browser",
"//extensions/browser",
]
}

View File

@ -0,0 +1,26 @@
# Copyright 2017 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.
import("//build/config/ui.gni")
import("//extensions/buildflags/buildflags.gni")
assert(enable_extensions)
source_set("views") {
sources = [
"app_window_frame_view.cc",
"app_window_frame_view.h",
]
deps = [
"//cc/paint",
"//chrome/app/theme:theme_resources",
"//extensions/browser",
"//extensions/common",
"//skia",
"//ui/gfx",
"//ui/strings",
"//ui/views",
]
}

2681
src/ash/BUILD.gn Normal file

File diff suppressed because it is too large Load Diff

276
src/ash/app_list/BUILD.gn Normal file
View File

@ -0,0 +1,276 @@
# Copyright 2014 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.
import("//build/config/ui.gni")
import("//testing/test.gni")
assert(is_chromeos)
component("app_list") {
sources = [
"app_list_export.h",
"app_list_metrics.cc",
"app_list_metrics.h",
"app_list_presenter_delegate.h",
"app_list_presenter_impl.cc",
"app_list_presenter_impl.h",
"app_list_util.cc",
"app_list_util.h",
"app_list_view_delegate.h",
"paged_view_structure.cc",
"paged_view_structure.h",
"views/app_list_drag_and_drop_host.h",
"views/app_list_folder_view.cc",
"views/app_list_folder_view.h",
"views/app_list_item_view.cc",
"views/app_list_item_view.h",
"views/app_list_main_view.cc",
"views/app_list_main_view.h",
"views/app_list_menu_model_adapter.cc",
"views/app_list_menu_model_adapter.h",
"views/app_list_page.cc",
"views/app_list_page.h",
"views/app_list_view.cc",
"views/app_list_view.h",
"views/apps_container_view.cc",
"views/apps_container_view.h",
"views/apps_grid_view.cc",
"views/apps_grid_view.h",
"views/apps_grid_view_folder_delegate.h",
"views/assistant/assistant_dialog_plate.cc",
"views/assistant/assistant_dialog_plate.h",
"views/assistant/assistant_main_stage.cc",
"views/assistant/assistant_main_stage.h",
"views/assistant/assistant_main_view.cc",
"views/assistant/assistant_main_view.h",
"views/assistant/assistant_page_view.cc",
"views/assistant/assistant_page_view.h",
"views/assistant/assistant_privacy_info_view.cc",
"views/assistant/assistant_privacy_info_view.h",
"views/contents_view.cc",
"views/contents_view.h",
"views/expand_arrow_view.cc",
"views/expand_arrow_view.h",
"views/folder_background_view.cc",
"views/folder_background_view.h",
"views/folder_header_view.cc",
"views/folder_header_view.h",
"views/folder_header_view_delegate.h",
"views/ghost_image_view.cc",
"views/ghost_image_view.h",
"views/page_switcher.cc",
"views/page_switcher.h",
"views/privacy_container_view.cc",
"views/privacy_container_view.h",
"views/privacy_info_view.cc",
"views/privacy_info_view.h",
"views/pulsing_block_view.cc",
"views/pulsing_block_view.h",
"views/remove_query_confirmation_dialog.cc",
"views/remove_query_confirmation_dialog.h",
"views/result_selection_controller.cc",
"views/result_selection_controller.h",
"views/search_box_view.cc",
"views/search_box_view.h",
"views/search_result_actions_view.cc",
"views/search_result_actions_view.h",
"views/search_result_actions_view_delegate.h",
"views/search_result_answer_card_view.cc",
"views/search_result_answer_card_view.h",
"views/search_result_base_view.cc",
"views/search_result_base_view.h",
"views/search_result_container_view.cc",
"views/search_result_container_view.h",
"views/search_result_list_view.cc",
"views/search_result_list_view.h",
"views/search_result_page_anchored_dialog.cc",
"views/search_result_page_anchored_dialog.h",
"views/search_result_page_view.cc",
"views/search_result_page_view.h",
"views/search_result_suggestion_chip_view.cc",
"views/search_result_suggestion_chip_view.h",
"views/search_result_tile_item_list_view.cc",
"views/search_result_tile_item_list_view.h",
"views/search_result_tile_item_view.cc",
"views/search_result_tile_item_view.h",
"views/search_result_view.cc",
"views/search_result_view.h",
"views/suggested_content_info_view.cc",
"views/suggested_content_info_view.h",
"views/suggestion_chip_container_view.cc",
"views/suggestion_chip_container_view.h",
"views/top_icon_animation_view.cc",
"views/top_icon_animation_view.h",
]
defines = [ "APP_LIST_IMPLEMENTATION" ]
deps = [
"//ash/app_list/resources",
"//ash/app_menu",
"//ash/assistant/model",
"//ash/assistant/ui",
"//ash/assistant/ui:constants",
"//ash/assistant/util",
"//ash/keyboard/ui",
"//ash/public/cpp/app_list/vector_icons",
"//ash/resources/vector_icons",
"//ash/search_box",
"//ash/strings",
"//base",
"//base:i18n",
"//base/third_party/dynamic_annotations",
"//cc/paint",
"//chromeos:chromeos",
"//chromeos/services/assistant/public/cpp",
"//chromeos/ui/vector_icons",
"//components/keyed_service/core",
"//components/sync",
"//mojo/public/cpp/bindings",
"//services/content/public/cpp",
"//skia",
"//third_party/icu",
"//ui/accessibility",
"//ui/aura",
"//ui/base",
"//ui/base/ime",
"//ui/base/ime/chromeos",
"//ui/compositor",
"//ui/compositor_extra",
"//ui/display",
"//ui/events",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/resources",
"//ui/strings",
"//ui/views",
"//ui/wm",
"//ui/wm/public",
]
# TODO(hejq): Remove this once app_list is migrated. http://crbug.com/733662
public_deps = [
"//ash/app_list/model:app_list_model",
"//ash/app_list/model:search_model",
"//ash/public/cpp",
"//base",
"//mojo/public/cpp/bindings",
"//services/content/public/mojom",
"//ui/aura",
"//ui/compositor",
"//ui/gfx/geometry",
"//ui/views",
"//ui/wm",
"//ui/wm/public",
]
}
static_library("test_support") {
testonly = true
sources = [
"test/app_list_test_model.cc",
"test/app_list_test_model.h",
"test/app_list_test_view_delegate.cc",
"test/app_list_test_view_delegate.h",
"test/test_app_list_color_provider.cc",
"test/test_app_list_color_provider.h",
"test/test_search_result.cc",
"test/test_search_result.h",
"views/test/apps_grid_view_test_api.cc",
"views/test/apps_grid_view_test_api.h",
]
deps = [
":app_list",
"//base",
"//services/content/public/cpp/test:test_support",
"//ui/base:base",
"//ui/events",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/views",
]
}
executable("app_list_demo") {
testonly = true
sources = [ "demo/app_list_demo_views.cc" ]
deps = [
":app_list",
":test_support",
"//base",
"//build/win:default_exe_manifest",
"//content",
"//content/public/browser",
"//skia",
"//ui/base",
"//ui/events",
"//ui/resources",
"//ui/resources:ui_test_pak",
"//ui/views",
"//ui/views_content_client",
"//url",
]
}
test("app_list_unittests") {
use_xvfb = use_xvfb_in_this_config
sources = [
"folder_image_unittest.cc",
"test/run_all_unittests.cc",
"views/app_list_item_view_unittest.cc",
"views/app_list_main_view_unittest.cc",
"views/app_list_menu_model_adapter_unittest.cc",
"views/app_list_view_unittest.cc",
"views/apps_grid_view_unittest.cc",
"views/folder_header_view_unittest.cc",
"views/privacy_container_view_unittest.cc",
"views/result_selection_controller_unittest.cc",
"views/search_box_view_unittest.cc",
"views/search_result_answer_card_view_unittest.cc",
"views/search_result_list_view_unittest.cc",
"views/search_result_page_view_unittest.cc",
"views/search_result_tile_item_list_view_unittest.cc",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
deps = [
":app_list",
":test_support",
"//ash/keyboard/ui",
"//ash/public/cpp",
"//ash/public/cpp/app_list/vector_icons",
"//ash/search_box",
"//base",
"//base/test:test_support",
"//chromeos/constants",
"//chromeos/services/assistant/public/cpp",
"//mojo/core/embedder",
"//mojo/public/cpp/bindings",
"//services/content/public/cpp",
"//services/content/public/cpp/test:test_support",
"//services/content/public/mojom",
"//skia",
"//testing/gtest",
"//ui/accessibility",
"//ui/base",
"//ui/compositor",
"//ui/events:test_support",
"//ui/gfx:test_support",
"//ui/gl:test_support",
"//ui/resources",
"//ui/views",
"//ui/views:test_support",
]
data_deps = [
"//third_party/mesa_headers",
"//ui/resources:ui_test_pak_data",
]
}

View File

@ -0,0 +1,56 @@
# Copyright 2017 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.
component("app_list_model") {
sources = [
"app_list_folder_item.cc",
"app_list_folder_item.h",
"app_list_item.cc",
"app_list_item.h",
"app_list_item_list.cc",
"app_list_item_list.h",
"app_list_item_list_observer.h",
"app_list_item_observer.h",
"app_list_model.cc",
"app_list_model.h",
"app_list_model_observer.h",
"folder_image.cc",
"folder_image.h",
]
defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ]
deps = [
"//ash/public/cpp:cpp",
"//base:i18n",
"//cc/paint",
"//components/sync",
"//skia",
"//third_party/icu",
"//ui/base",
"//ui/gfx",
]
}
component("search_model") {
sources = [
"search/search_box_model.cc",
"search/search_box_model.h",
"search/search_box_model_observer.h",
"search/search_model.cc",
"search/search_model.h",
"search/search_result.cc",
"search/search_result.h",
"search/search_result_observer.h",
]
defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ]
deps = [
"//ash/public/cpp:cpp",
"//base:i18n",
"//ui/base",
"//ui/gfx",
]
}

View File

@ -0,0 +1,20 @@
# Copyright 2015 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.
import("//tools/grit/grit_rule.gni")
import("//tools/grit/repack.gni")
group("resources") {
public_deps = [ ":resources_grd" ]
}
grit("resources_grd") {
source = "app_list_resources.grd"
outputs = [
"grit/app_list_resources.h",
"app_list_resources_100_percent.pak",
"app_list_resources_200_percent.pak",
"app_list_resources_300_percent.pak",
]
}

36
src/ash/app_menu/BUILD.gn Normal file
View File

@ -0,0 +1,36 @@
# Copyright 2018 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.
import("//build/config/ui.gni")
assert(is_chromeos)
component("app_menu") {
sources = [
"app_menu_model_adapter.cc",
"app_menu_model_adapter.h",
"notification_item_view.cc",
"notification_item_view.h",
"notification_menu_controller.cc",
"notification_menu_controller.h",
"notification_menu_header_view.cc",
"notification_menu_header_view.h",
"notification_menu_view.cc",
"notification_menu_view.h",
"notification_overflow_view.cc",
"notification_overflow_view.h",
]
defines = [ "APP_MENU_IMPLEMENTATION" ]
deps = [
"//ash/public/cpp",
"//base",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/message_center",
"//ui/strings:ui_strings_grit",
"//ui/views",
]
}

View File

@ -0,0 +1,57 @@
# Copyright 2018 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.
assert(is_chromeos)
component("model") {
output_name = "assistant_model"
defines = [ "IS_ASSISTANT_MODEL_IMPL" ]
sources = [
"assistant_alarm_timer_model.cc",
"assistant_alarm_timer_model.h",
"assistant_alarm_timer_model_observer.h",
"assistant_interaction_model.cc",
"assistant_interaction_model.h",
"assistant_interaction_model_observer.h",
"assistant_notification_model.cc",
"assistant_notification_model.h",
"assistant_notification_model_observer.h",
"assistant_query.cc",
"assistant_query.h",
"assistant_query_history.cc",
"assistant_query_history.h",
"assistant_response.cc",
"assistant_response.h",
"assistant_response_observer.h",
"assistant_screen_context_model.cc",
"assistant_screen_context_model.h",
"assistant_screen_context_model_observer.h",
"assistant_suggestions_model.cc",
"assistant_suggestions_model.h",
"assistant_suggestions_model_observer.h",
"assistant_ui_model.cc",
"assistant_ui_model.h",
"assistant_ui_model_observer.h",
"ui/assistant_card_element.cc",
"ui/assistant_card_element.h",
"ui/assistant_error_element.cc",
"ui/assistant_error_element.h",
"ui/assistant_text_element.cc",
"ui/assistant_text_element.h",
"ui/assistant_ui_element.cc",
"ui/assistant_ui_element.h",
]
deps = [
"//ash/assistant/ui:constants",
"//ash/public/cpp",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/assistant/public/mojom",
"//services/content/public/cpp",
"//ui/accessibility/mojom",
"//ui/gfx/geometry",
]
}

View File

@ -0,0 +1,123 @@
# Copyright 2018 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.
import("//build/config/ui.gni")
import("//chromeos/assistant/assistant.gni")
assert(is_chromeos)
component("constants") {
output_name = "assistant_ui_constants"
defines = [ "IS_ASSISTANT_UI_CONSTANTS_IMPL" ]
sources = [
"assistant_ui_constants.cc",
"assistant_ui_constants.h",
]
deps = [
"//base",
"//skia",
"//ui/aura",
"//ui/base",
"//ui/gfx",
]
}
component("ui") {
output_name = "assistant_ui"
defines = [ "IS_ASSISTANT_UI_IMPL" ]
sources = [
"assistant_view_delegate.h",
"assistant_view_ids.h",
"assistant_web_container_view.cc",
"assistant_web_container_view.h",
"assistant_web_view_delegate.h",
"base/assistant_button.cc",
"base/assistant_button.h",
"base/assistant_button_listener.h",
"base/assistant_scroll_view.cc",
"base/assistant_scroll_view.h",
"base/stack_layout.cc",
"base/stack_layout.h",
"dialog_plate/mic_view.cc",
"dialog_plate/mic_view.h",
"logo_view/logo_view.cc",
"logo_view/logo_view.h",
"main_stage/animated_container_view.cc",
"main_stage/animated_container_view.h",
"main_stage/assistant_card_element_view.cc",
"main_stage/assistant_card_element_view.h",
"main_stage/assistant_error_element_view.cc",
"main_stage/assistant_error_element_view.h",
"main_stage/assistant_footer_view.cc",
"main_stage/assistant_footer_view.h",
"main_stage/assistant_onboarding_suggestion_view.cc",
"main_stage/assistant_onboarding_suggestion_view.h",
"main_stage/assistant_onboarding_view.cc",
"main_stage/assistant_onboarding_view.h",
"main_stage/assistant_opt_in_view.cc",
"main_stage/assistant_opt_in_view.h",
"main_stage/assistant_progress_indicator.cc",
"main_stage/assistant_progress_indicator.h",
"main_stage/assistant_query_view.cc",
"main_stage/assistant_query_view.h",
"main_stage/assistant_text_element_view.cc",
"main_stage/assistant_text_element_view.h",
"main_stage/assistant_ui_element_view.cc",
"main_stage/assistant_ui_element_view.h",
"main_stage/assistant_ui_element_view_animator.cc",
"main_stage/assistant_ui_element_view_animator.h",
"main_stage/assistant_ui_element_view_factory.cc",
"main_stage/assistant_ui_element_view_factory.h",
"main_stage/assistant_zero_state_view.cc",
"main_stage/assistant_zero_state_view.h",
"main_stage/element_animator.cc",
"main_stage/element_animator.h",
"main_stage/suggestion_chip_view.cc",
"main_stage/suggestion_chip_view.h",
"main_stage/suggestion_container_view.cc",
"main_stage/suggestion_container_view.h",
"main_stage/ui_element_container_view.cc",
"main_stage/ui_element_container_view.h",
]
deps = [
"//ash/assistant/model",
"//ash/assistant/ui:constants",
"//ash/assistant/util",
"//ash/keyboard/ui",
"//ash/public/cpp",
"//ash/resources/vector_icons",
"//ash/strings",
"//base",
"//chromeos/assistant:buildflags",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/assistant/public/mojom",
"//chromeos/ui/vector_icons",
"//services/content/public/cpp",
"//ui/aura",
"//ui/compositor",
"//ui/gfx",
"//ui/views",
"//ui/views/window/vector_icons",
"//ui/wm",
]
if (enable_cros_libassistant) {
sources += [
"logo_view/logo_view_impl.cc",
"logo_view/logo_view_impl.h",
"logo_view/shape/mic_part_shape.cc",
"logo_view/shape/mic_part_shape.h",
"logo_view/shape/shape.cc",
"logo_view/shape/shape.h",
]
deps += [ "//chromeos/assistant/internal/logo_view" ]
}
}

View File

@ -0,0 +1,20 @@
# Copyright 2020 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.
static_library("test_support") {
testonly = true
sources = [
"mock_assistant_view_delegate.cc",
"mock_assistant_view_delegate.h",
]
deps = [
"//ash/assistant/ui",
"//base",
"//testing/gmock",
"//testing/gtest",
"//ui/gfx",
]
}

View File

@ -0,0 +1,42 @@
# 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.
assert(is_chromeos)
component("util") {
output_name = "assistant_util"
defines = [ "IS_ASSISTANT_UTIL_IMPL" ]
sources = [
"animation_util.cc",
"animation_util.h",
"assistant_util.cc",
"assistant_util.h",
"deep_link_util.cc",
"deep_link_util.h",
"histogram_util.cc",
"histogram_util.h",
"i18n_util.cc",
"i18n_util.h",
"resource_util.cc",
"resource_util.h",
]
deps = [
"//ash/assistant/model",
"//ash/public/cpp",
"//base",
"//base:i18n",
"//chromeos/constants",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/assistant/public/mojom",
"//chromeos/ui/vector_icons",
"//net",
"//ui/base",
"//ui/gfx",
"//ui/views",
"//url",
]
}

View File

@ -0,0 +1,11 @@
# Copyright 2020 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.
static_library("test_support") {
testonly = true
sources = [ "macros.h" ]
deps = []
}

View File

@ -0,0 +1,178 @@
# Copyright 2014 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.
import("//mojo/public/tools/bindings/mojom.gni")
import("//testing/test.gni")
import("//third_party/google_input_tools/closure.gni")
import("//third_party/google_input_tools/inputview.gni")
import("//tools/grit/grit_rule.gni")
assert(is_chromeos)
component("ui") {
sources = [
"container_behavior.cc",
"container_behavior.h",
"container_floating_behavior.cc",
"container_floating_behavior.h",
"container_full_width_behavior.cc",
"container_full_width_behavior.h",
"display_util.cc",
"display_util.h",
"drag_descriptor.h",
"keyboard_event_handler.cc",
"keyboard_event_handler.h",
"keyboard_export.h",
"keyboard_layout_delegate.h",
"keyboard_layout_manager.cc",
"keyboard_layout_manager.h",
"keyboard_ui.cc",
"keyboard_ui.h",
"keyboard_ui_controller.cc",
"keyboard_ui_controller.h",
"keyboard_ui_factory.cc",
"keyboard_ui_factory.h",
"keyboard_ui_model.cc",
"keyboard_ui_model.h",
"keyboard_ukm_recorder.cc",
"keyboard_ukm_recorder.h",
"keyboard_util.cc",
"keyboard_util.h",
"notification_manager.cc",
"notification_manager.h",
"queued_container_type.cc",
"queued_container_type.h",
"queued_display_change.cc",
"queued_display_change.h",
"resources/keyboard_resource_util.cc",
"resources/keyboard_resource_util.h",
"shaped_window_targeter.cc",
"shaped_window_targeter.h",
]
defines = [ "KEYBOARD_IMPLEMENTATION" ]
deps = [
":resources",
"//ash/public/cpp",
"//base",
"//services/metrics/public/cpp:ukm_builders",
"//ui/aura",
"//ui/base",
"//ui/base/ime",
"//ui/compositor",
"//ui/display:display",
"//ui/events",
"//ui/events:dom_keycode_converter",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/wm",
]
if (use_ozone) {
deps += [ "//ui/ozone" ]
}
data_deps = [ ":resources" ]
}
static_library("test_support") {
testonly = true
sources = [
"test/keyboard_test_util.cc",
"test/keyboard_test_util.h",
"test/test_keyboard_controller_observer.cc",
"test/test_keyboard_controller_observer.h",
"test/test_keyboard_layout_delegate.cc",
"test/test_keyboard_layout_delegate.h",
"test/test_keyboard_ui_factory.cc",
"test/test_keyboard_ui_factory.h",
]
deps = [
":ui",
"//ash/public/cpp",
"//base",
"//ui/aura",
"//ui/aura:test_support",
"//ui/base:test_support",
"//ui/display",
]
}
grit("resources_grit") {
source = "keyboard_resources.grd"
outputs = [
"grit/keyboard_resources.h",
"grit/keyboard_resources_map.h",
"keyboard_resources.pak",
]
input_tools_root_dir = "//third_party/google_input_tools/src/chrome/os"
inputview_gen_js = "$root_gen_dir/ash/keyboard/ui/resources/inputview.js"
grit_flags = [
"-E",
"input_tools_root_dir=" + rebase_path(input_tools_root_dir, "."),
"-E",
"inputview_gen_js=" + rebase_path(inputview_gen_js, root_build_dir),
]
deps = [ ":inputview" ]
}
copy("resources") {
sources = [ "$target_gen_dir/keyboard_resources.pak" ]
outputs = [ "$root_out_dir/keyboard_resources.pak" ]
public_deps = [ ":resources_grit" ]
}
build_closure("inputview") {
sources = inputview_sources
target = "$target_gen_dir/resources/inputview.js"
path = rebase_path("//third_party/google_input_tools")
}
test("keyboard_unittests") {
use_xvfb = use_xvfb_in_this_config
sources = [
"container_floating_behavior_unittest.cc",
"container_full_width_behavior_unittest.cc",
"keyboard_event_handler_unittest.cc",
"keyboard_ui_controller_unittest.cc",
"keyboard_ui_model_unittest.cc",
"keyboard_ukm_recorder_unittest.cc",
"keyboard_util_unittest.cc",
"notification_manager_unittest.cc",
"test/run_all_unittests.cc",
]
deps = [
":test_support",
":ui",
"//ash/public/cpp",
"//base",
"//base/test:test_support",
"//components/ukm:test_support",
"//mojo/core/embedder",
"//testing/gmock",
"//testing/gtest",
"//ui/aura:test_support",
"//ui/base",
"//ui/base:test_support",
"//ui/base/ime/init",
"//ui/compositor:test_support",
"//ui/events:test_support",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gl:test_support",
"//ui/resources:ui_test_pak",
"//ui/wm",
]
data_deps = [ "//ui/resources:ui_test_pak_data" ]
if (use_ozone) {
deps += [ "//ui/ozone" ]
}
}

View File

@ -0,0 +1,17 @@
# Copyright 2018 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.
import("//tools/grit/grit_rule.gni")
grit("resources") {
source = "login_resources.grd"
outputs = [
"grit/login_resources.h",
"grit/login_resources_map.cc",
"grit/login_resources_map.h",
"login_resources_100_percent.pak",
"login_resources_200_percent.pak",
"login_resources_300_percent.pak",
]
}

442
src/ash/public/cpp/BUILD.gn Normal file
View File

@ -0,0 +1,442 @@
# Copyright 2016 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.
import("//mojo/public/tools/bindings/mojom.gni")
# C++ headers and sources that can be used outside ash.
component("cpp") {
sources = [
"accelerators.cc",
"accelerators.h",
"accessibility_controller.cc",
"accessibility_controller.h",
"accessibility_controller_client.h",
"accessibility_controller_enums.h",
"accessibility_event_rewriter_delegate.h",
"accessibility_focus_ring_controller.cc",
"accessibility_focus_ring_controller.h",
"accessibility_focus_ring_info.cc",
"accessibility_focus_ring_info.h",
"ambient/ambient_backend_controller.cc",
"ambient/ambient_backend_controller.h",
"ambient/ambient_client.cc",
"ambient/ambient_client.h",
"ambient/ambient_metrics.cc",
"ambient/ambient_metrics.h",
"ambient/ambient_prefs.cc",
"ambient/ambient_prefs.h",
"ambient/ambient_ui_model.cc",
"ambient/ambient_ui_model.h",
"ambient/common/ambient_settings.cc",
"ambient/common/ambient_settings.h",
"ambient/fake_ambient_backend_controller_impl.cc",
"ambient/fake_ambient_backend_controller_impl.h",
"android_intent_helper.cc",
"android_intent_helper.h",
"app_list/app_list_client.h",
"app_list/app_list_color_provider.cc",
"app_list/app_list_color_provider.h",
"app_list/app_list_config.cc",
"app_list/app_list_config.h",
"app_list/app_list_config_provider.cc",
"app_list/app_list_config_provider.h",
"app_list/app_list_controller.cc",
"app_list/app_list_controller.h",
"app_list/app_list_controller_observer.h",
"app_list/app_list_features.cc",
"app_list/app_list_features.h",
"app_list/app_list_metrics.cc",
"app_list/app_list_metrics.h",
"app_list/app_list_notifier.h",
"app_list/app_list_switches.cc",
"app_list/app_list_switches.h",
"app_list/app_list_types.cc",
"app_list/app_list_types.h",
"app_list/internal_app_id_constants.h",
"app_menu_constants.h",
"app_types.h",
"arc_app_id_provider.cc",
"arc_app_id_provider.h",
"ash_constants.h",
"ash_features.cc",
"ash_features.h",
"ash_pref_names.cc",
"ash_pref_names.h",
"ash_public_export.h",
"ash_switches.cc",
"ash_switches.h",
"ash_typography.cc",
"ash_typography.h",
"ash_view_ids.h",
"assistant/assistant_client.cc",
"assistant/assistant_client.h",
"assistant/assistant_interface_binder.cc",
"assistant/assistant_interface_binder.h",
"assistant/assistant_setup.cc",
"assistant/assistant_setup.h",
"assistant/assistant_state.cc",
"assistant/assistant_state.h",
"assistant/assistant_state_base.cc",
"assistant/assistant_state_base.h",
"assistant/assistant_web_view.cc",
"assistant/assistant_web_view.h",
"assistant/assistant_web_view_factory.cc",
"assistant/assistant_web_view_factory.h",
"assistant/controller/assistant_alarm_timer_controller.cc",
"assistant/controller/assistant_alarm_timer_controller.h",
"assistant/controller/assistant_controller.cc",
"assistant/controller/assistant_controller.h",
"assistant/controller/assistant_controller_observer.h",
"assistant/controller/assistant_interaction_controller.cc",
"assistant/controller/assistant_interaction_controller.h",
"assistant/controller/assistant_notification_controller.cc",
"assistant/controller/assistant_notification_controller.h",
"assistant/controller/assistant_screen_context_controller.cc",
"assistant/controller/assistant_screen_context_controller.h",
"assistant/controller/assistant_suggestions_controller.cc",
"assistant/controller/assistant_suggestions_controller.h",
"assistant/controller/assistant_ui_controller.cc",
"assistant/controller/assistant_ui_controller.h",
"assistant/conversation_starter.cc",
"assistant/conversation_starter.h",
"assistant/conversation_starters_client.cc",
"assistant/conversation_starters_client.h",
"back_gesture_contextual_nudge_controller.h",
"back_gesture_contextual_nudge_delegate.h",
"caption_buttons/caption_button_model.h",
"caption_buttons/frame_back_button.cc",
"caption_buttons/frame_back_button.h",
"caption_buttons/frame_caption_button_container_view.cc",
"caption_buttons/frame_caption_button_container_view.h",
"caption_buttons/frame_size_button.cc",
"caption_buttons/frame_size_button.h",
"caption_buttons/frame_size_button_delegate.h",
"caption_buttons/snap_controller.cc",
"caption_buttons/snap_controller.h",
"cast_config_controller.cc",
"cast_config_controller.h",
"child_accounts/parent_access_controller.cc",
"child_accounts/parent_access_controller.h",
"clipboard_history_controller.cc",
"clipboard_history_controller.h",
"clipboard_image_model_factory.cc",
"clipboard_image_model_factory.h",
"default_frame_header.cc",
"default_frame_header.h",
"default_scale_factor_retriever.cc",
"default_scale_factor_retriever.h",
"desks_helper.cc",
"desks_helper.h",
"esim_manager.cc",
"esim_manager.h",
"file_icon_util.cc",
"file_icon_util.h",
"fps_counter.cc",
"fps_counter.h",
"frame_header.cc",
"frame_header.h",
"frame_utils.cc",
"frame_utils.h",
"gesture_action_type.h",
"holding_space/holding_space_client.h",
"holding_space/holding_space_constants.h",
"holding_space/holding_space_controller.cc",
"holding_space/holding_space_controller.h",
"holding_space/holding_space_controller_observer.h",
"holding_space/holding_space_image.cc",
"holding_space/holding_space_image.h",
"holding_space/holding_space_item.cc",
"holding_space/holding_space_item.h",
"holding_space/holding_space_metrics.cc",
"holding_space/holding_space_metrics.h",
"holding_space/holding_space_model.cc",
"holding_space/holding_space_model.h",
"holding_space/holding_space_model_observer.h",
"holding_space/holding_space_prefs.cc",
"holding_space/holding_space_prefs.h",
"image_downloader.cc",
"image_downloader.h",
"ime_controller.cc",
"ime_controller.h",
"ime_controller_client.h",
"ime_info.cc",
"ime_info.h",
"immersive/immersive_context.cc",
"immersive/immersive_context.h",
"immersive/immersive_focus_watcher.cc",
"immersive/immersive_focus_watcher.h",
"immersive/immersive_fullscreen_controller.cc",
"immersive/immersive_fullscreen_controller.h",
"immersive/immersive_fullscreen_controller_delegate.h",
"immersive/immersive_revealed_lock.cc",
"immersive/immersive_revealed_lock.h",
"in_session_auth_dialog_client.h",
"in_session_auth_dialog_controller.cc",
"in_session_auth_dialog_controller.h",
"keyboard/arc/arc_input_method_bounds_tracker.cc",
"keyboard/arc/arc_input_method_bounds_tracker.h",
"keyboard/keyboard_config.h",
"keyboard/keyboard_controller.cc",
"keyboard/keyboard_controller.h",
"keyboard/keyboard_controller_observer.h",
"keyboard/keyboard_switches.cc",
"keyboard/keyboard_switches.h",
"keyboard/keyboard_types.h",
"keyboard_shortcut_viewer.h",
"kiosk_app_menu.cc",
"kiosk_app_menu.h",
"locale_update_controller.cc",
"locale_update_controller.h",
"lock_screen_widget_factory.cc",
"lock_screen_widget_factory.h",
"login_accelerators.cc",
"login_accelerators.h",
"login_constants.h",
"login_screen.cc",
"login_screen.h",
"login_screen_client.h",
"login_screen_model.cc",
"login_screen_model.h",
"login_screen_test_api.h",
"login_types.cc",
"login_types.h",
"media_client.h",
"media_controller.cc",
"media_controller.h",
"media_notification_provider.cc",
"media_notification_provider.h",
"media_notification_provider_observer.h",
"message_center/arc_notification_constants.h",
"message_center/arc_notification_manager_base.cc",
"message_center/arc_notification_manager_base.h",
"message_center/arc_notification_manager_delegate.h",
"message_center/arc_notifications_host_initializer.cc",
"message_center/arc_notifications_host_initializer.h",
"metrics_util.cc",
"metrics_util.h",
"nearby_share_controller.h",
"nearby_share_delegate.h",
"network_config_service.cc",
"network_config_service.h",
"network_icon_image_source.cc",
"network_icon_image_source.h",
"new_window_delegate.cc",
"new_window_delegate.h",
"night_light_controller.cc",
"night_light_controller.h",
"note_taking_client.cc",
"note_taking_client.h",
"notification_utils.cc",
"notification_utils.h",
"notifier_metadata.cc",
"notifier_metadata.h",
"notifier_settings_controller.cc",
"notifier_settings_controller.h",
"notifier_settings_observer.h",
"pagination/pagination_controller.cc",
"pagination/pagination_controller.h",
"pagination/pagination_model.cc",
"pagination/pagination_model.h",
"pagination/pagination_model_observer.h",
"power_utils.cc",
"power_utils.h",
"presentation_time_recorder.cc",
"presentation_time_recorder.h",
"privacy_screen_dlp_helper.cc",
"privacy_screen_dlp_helper.h",
"quick_answers/controller/quick_answers_browser_client.cc",
"quick_answers/controller/quick_answers_browser_client.h",
"quick_answers/controller/quick_answers_controller.cc",
"quick_answers/controller/quick_answers_controller.h",
"rounded_corner_decorator.cc",
"rounded_corner_decorator.h",
"rounded_image_view.cc",
"rounded_image_view.h",
"scale_utility.cc",
"scale_utility.h",
"scoped_guest_button_blocker.h",
"scoped_singleton_resetter_for_test.h",
"screen_backlight.cc",
"screen_backlight.h",
"screen_backlight_observer.h",
"screen_backlight_type.h",
"select_to_speak_event_handler_delegate.h",
"session/session_activation_observer.h",
"session/session_controller.cc",
"session/session_controller.h",
"session/session_controller_client.h",
"session/session_observer.cc",
"session/session_observer.h",
"session/session_types.cc",
"session/session_types.h",
"session/user_info.cc",
"session/user_info.h",
"shelf_item.cc",
"shelf_item.h",
"shelf_item_delegate.cc",
"shelf_item_delegate.h",
"shelf_model.cc",
"shelf_model.h",
"shelf_model_observer.h",
"shelf_prefs.cc",
"shelf_prefs.h",
"shelf_types.cc",
"shelf_types.h",
"shelf_ui_info.cc",
"shelf_ui_info.h",
"shell_window_ids.cc",
"shell_window_ids.h",
"shutdown_controller.cc",
"shutdown_controller.h",
"stylus_utils.cc",
"stylus_utils.h",
"system_tray.cc",
"system_tray.h",
"system_tray_client.h",
"system_tray_focus_observer.h",
"tablet_mode.cc",
"tablet_mode.h",
"tablet_mode_observer.h",
"toast_data.cc",
"toast_data.h",
"toast_manager.cc",
"toast_manager.h",
"update_types.h",
"view_shadow.cc",
"view_shadow.h",
"wallpaper_controller.cc",
"wallpaper_controller.h",
"wallpaper_controller_client.h",
"wallpaper_controller_observer.cc",
"wallpaper_controller_observer.h",
"wallpaper_info.h",
"wallpaper_types.h",
"window_animation_types.h",
"window_backdrop.cc",
"window_backdrop.h",
"window_pin_type.cc",
"window_pin_type.h",
"window_properties.cc",
"window_properties.h",
"window_state_type.cc",
"window_state_type.h",
]
defines = [ "ASH_PUBLIC_IMPLEMENTATION" ]
assert_no_deps = [
"//ash/public/cpp/external_arc",
"//components/arc",
"//components/exo",
]
deps = [
"//base/util/values:values_util",
"//chromeos/constants",
"//chromeos/dbus/power:power_manager_proto",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/cellular_setup:in_process_esim_manager",
"//chromeos/services/network_config:in_process_instance",
"//chromeos/ui",
"//chromeos/ui/vector_icons",
"//components/pref_registry",
"//components/prefs",
"//components/sync:rest_of_sync",
"//mojo/public/cpp/bindings",
"//net/traffic_annotation",
"//services/network/public/cpp:cpp",
"//skia/public/mojom",
"//ui/aura",
"//ui/chromeos/strings",
"//ui/compositor_extra",
"//ui/display",
"//ui/events/devices",
"//ui/message_center/public/cpp",
"//ui/views",
"//ui/views/window/vector_icons",
"//ui/wm",
"//ui/wm/public",
]
public_deps = [
"//ash/public/mojom",
"//base",
"//chromeos/components/security_token_pin",
"//chromeos/services/assistant/public/mojom",
"//chromeos/services/cellular_setup/public/mojom",
"//chromeos/services/network_config/public/mojom",
"//components/arc/mojom:notifications",
"//components/session_manager:base",
"//components/user_manager",
"//ui/base/ime/chromeos:ime_types",
"//ui/gfx",
]
output_name = "ash_public_cpp"
}
source_set("unit_tests") {
testonly = true
sources = [
"ambient/ambient_metrics_unittest.cc",
"android_intent_helper_unittest.cc",
"app_list/app_list_config_provider_unittest.cc",
"default_scale_factor_retriever_unittest.cc",
"file_icon_util_unittest.cc",
"holding_space/holding_space_item_unittest.cc",
"metrics_util_unittest.cc",
"pagination/pagination_model_unittest.cc",
"power_utils_unittest.cc",
"rounded_corner_decorator_unittest.cc",
"shelf_model_unittest.cc",
"view_shadow_unittest.cc",
]
deps = [
":cpp",
"//base",
"//base/test:test_support",
"//mojo/public/cpp/bindings",
"//testing/gtest",
"//ui/aura:test_support",
"//ui/compositor_extra",
"//ui/gfx:test_support",
"//ui/views",
"//ui/views:test_support",
]
}
source_set("test_support") {
testonly = true
sources = [
"immersive/immersive_fullscreen_controller_test_api.cc",
"immersive/immersive_fullscreen_controller_test_api.h",
"test/test_ambient_client.cc",
"test/test_ambient_client.h",
"test/test_image_downloader.cc",
"test/test_image_downloader.h",
"test/test_keyboard_controller_observer.cc",
"test/test_keyboard_controller_observer.h",
"test/test_nearby_share_delegate.cc",
"test/test_nearby_share_delegate.h",
"test/test_new_window_delegate.cc",
"test/test_new_window_delegate.h",
"test/test_system_tray_client.cc",
"test/test_system_tray_client.h",
"test/test_tablet_mode.cc",
"test/test_tablet_mode.h",
]
deps = [
":cpp",
"//base",
"//services/device/public/cpp:test_support",
"//services/network/public/cpp:cpp",
"//ui/aura",
"//ui/aura:test_support",
"//ui/gfx",
"//ui/gfx:test_support",
"//ui/views",
]
}

View File

@ -0,0 +1,40 @@
# Copyright 2017 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.
import("//components/vector_icons/vector_icons.gni")
aggregate_vector_icons2("app_list_vector_icons") {
icon_directory = "."
sources = [
"arrow_up.icon",
"badge_instant.icon",
"badge_play.icon",
"badge_rating.icon",
"bookmark.icon",
"domain.icon",
"equal.icon",
"google_black.icon",
"google_color.icon",
"history.icon",
"mic_black.icon",
"search.icon",
"search_engine_not_google.icon",
"search_result_append.icon",
"search_result_remove.icon",
"vertical_bar_end.icon",
"vertical_bar_middle.icon",
"vertical_bar_single.icon",
"vertical_bar_start.icon",
]
}
source_set("vector_icons") {
sources = get_target_outputs(":app_list_vector_icons")
deps = [
":app_list_vector_icons",
"//skia",
]
}

View File

@ -0,0 +1,16 @@
static_library("test_support") {
testonly = true
sources = [
"mock_assistant_controller.cc",
"mock_assistant_controller.h",
"mock_assistant_state.cc",
"mock_assistant_state.h",
]
deps = [
"//ash/public/cpp",
"//testing/gmock",
"//url",
]
}

View File

@ -0,0 +1,93 @@
# Copyright 2020 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.
import("//build/config/ui.gni")
static_library("external_arc") {
sources = [
"keyboard/arc_input_method_surface_manager.cc",
"keyboard/arc_input_method_surface_manager.h",
"message_center/arc_notification_content_view.cc",
"message_center/arc_notification_content_view.h",
"message_center/arc_notification_delegate.cc",
"message_center/arc_notification_delegate.h",
"message_center/arc_notification_item.h",
"message_center/arc_notification_item_impl.cc",
"message_center/arc_notification_item_impl.h",
"message_center/arc_notification_manager.cc",
"message_center/arc_notification_manager.h",
"message_center/arc_notification_surface.h",
"message_center/arc_notification_surface_impl.cc",
"message_center/arc_notification_surface_impl.h",
"message_center/arc_notification_surface_manager.cc",
"message_center/arc_notification_surface_manager.h",
"message_center/arc_notification_surface_manager_impl.cc",
"message_center/arc_notification_surface_manager_impl.h",
"message_center/arc_notification_view.cc",
"message_center/arc_notification_view.h",
"toast/arc_toast_surface_manager.cc",
"toast/arc_toast_surface_manager.h",
]
defines = [ "ASH_PUBLIC_IMPLEMENTATION" ]
deps = [
"//ash/public/cpp",
"//base",
"//chromeos/constants",
"//components/account_id",
"//components/arc:arc_metrics_constants",
"//components/arc:connection_holder",
"//components/arc/mojom:notifications",
"//components/exo",
"//mojo/public/cpp/system",
"//ui/message_center",
"//ui/views",
"//ui/wm",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"keyboard/arc_input_method_surface_manager_unittest.cc",
"message_center/arc_notification_content_view_unittest.cc",
"message_center/arc_notification_manager_unittest.cc",
"message_center/arc_notification_view_unittest.cc",
"toast/arc_toast_surface_manager_unittest.cc",
]
public_deps = [ "//ash:test_support" ]
deps = [
":external_arc",
":test_support",
"//ash",
"//ash:test_support",
"//ash/public/cpp",
"//base/test:test_support",
"//components/arc:connection_holder",
"//components/arc:notification_test_support",
"//components/exo",
"//components/exo:test_support",
"//testing/gmock",
"//ui/aura:test_support",
"//ui/base:test_support",
"//ui/events:test_support",
"//ui/message_center:test_support",
"//ui/views:test_support",
]
assert_no_deps = [ "//compponents/arc:arc_base" ]
}
source_set("test_support") {
testonly = true
sources = [
"message_center/mock_arc_notification_item.cc",
"message_center/mock_arc_notification_item.h",
"message_center/mock_arc_notification_surface.cc",
"message_center/mock_arc_notification_surface.h",
]
deps = [
":external_arc",
"//ash/public/cpp",
"//base",
"//ui/aura",
]
}

View File

@ -0,0 +1,13 @@
# Copyright 2018 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.
import("//tools/grit/grit_rule.gni")
grit("ash_public_unscaled_resources") {
source = "ash_public_unscaled_resources.grd"
outputs = [
"grit/ash_public_unscaled_resources.h",
"ash_public_unscaled_resources.pak",
]
}

View File

@ -0,0 +1,36 @@
# Copyright 2015 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.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
disable_variants = true
sources = [
"assistant_volume_control.mojom",
"cros_display_config.mojom",
"tray_action.mojom",
"voice_interaction_controller.mojom",
]
public_deps = [
"//chromeos/components/proximity_auth/public/mojom",
"//components/account_id/mojom",
"//components/sync/mojom",
"//mojo/public/mojom/base",
"//services/content/public/mojom",
"//services/preferences/public/mojom",
"//skia/public/mojom",
"//ui/display/mojom:mojom",
"//ui/gfx/geometry/mojom",
"//ui/gfx/image/mojom",
"//ui/gfx/range/mojom",
"//url/mojom:url_mojom_gurl",
]
component_output_prefix = "ash_public_interfaces"
export_class_attribute = "ASH_PUBLIC_EXPORT"
export_define = "ASH_PUBLIC_IMPLEMENTATION=1"
export_header = "ash/public/cpp/ash_public_export.h"
}

View File

@ -0,0 +1,88 @@
# Copyright 2014 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.
import("//tools/grit/grit_rule.gni")
import("//tools/grit/repack.gni")
import("//ui/base/ui_features.gni")
assert(is_chromeos)
assert(enable_hidpi)
# Repacks resources needed for ash_unittests, etc. at a given scale.
# TODO(msw): Use ui_test.pak instead of its pieces? (no 200% support?)
template("ash_test_resources") {
percent = invoker.percent
repack("ash_test_resources_${target_name}") {
output = "$root_build_dir/${target_name}.pak"
sources = [
"$root_gen_dir/ash/app_list/resources/app_list_resources_${percent}_percent.pak",
"$root_gen_dir/ash/login/resources/login_resources_${percent}_percent.pak",
"$root_gen_dir/ash/public/cpp/resources/ash_public_unscaled_resources.pak",
"$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_${percent}_percent.pak",
"$root_gen_dir/ui/resources/ui_resources_${percent}_percent.pak",
"$root_gen_dir/ui/views/resources/views_resources_${percent}_percent.pak",
]
if (percent == "100") {
sources += [
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
]
}
if (defined(invoker.sources)) {
sources += invoker.sources
}
deps = [
"//ash/app_list/resources",
"//ash/login/resources",
"//ash/public/cpp/resources:ash_public_unscaled_resources",
"//mojo/public/js:resources",
"//ui/chromeos/resources",
"//ui/resources",
"//ui/views/resources",
]
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (percent == "100") {
# TODO(msw): This seems bad, but follows repack_ui_test_pak's example.
deps += [ "//third_party/blink/public:resources_grit" ]
sources += [
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
]
}
}
}
ash_test_resources("100_percent") {
percent = "100"
}
ash_test_resources("200_percent") {
percent = "200"
}
# There is no with_content_200_percent as content resources are only available
# at 100%.
ash_test_resources("with_content_100_percent") {
percent = "100"
sources = [
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/content/dev_ui_content_resources.pak",
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
"$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
]
deps = [
"//content:content_resources",
"//content:dev_ui_content_resources",
"//third_party/blink/public:scaled_resources_100_percent",
"//third_party/blink/public/strings",
]
}

View File

@ -0,0 +1,345 @@
# Copyright 2016 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.
import("//build/config/chrome_build.gni")
import("//components/vector_icons/vector_icons.gni")
aggregate_vector_icons2("ash_vector_icons") {
icon_directory = "."
sources = [
"always_show_shelf.icon",
"auto_hide.icon",
"autoclick.icon",
"autoclick_close.icon",
"autoclick_double_click.icon",
"autoclick_drag.icon",
"autoclick_left_click.icon",
"autoclick_pause.icon",
"autoclick_position_bottom_left.icon",
"autoclick_position_bottom_right.icon",
"autoclick_position_top_left.icon",
"autoclick_position_top_right.icon",
"autoclick_right_click.icon",
"autoclick_scroll.icon",
"autoclick_scroll_down.icon",
"autoclick_scroll_left.icon",
"autoclick_scroll_right.icon",
"autoclick_scroll_up.icon",
"battery.icon",
"captive_portal.icon",
"capture_mode.icon",
"capture_mode_circle_stop.icon",
"capture_mode_fullscreen.icon",
"capture_mode_image.icon",
"capture_mode_region.icon",
"capture_mode_video.icon",
"capture_mode_window.icon",
"check_circle.icon",
"chevron_right.icon",
"clipboard.icon",
"clipboard_launcher_inner.icon",
"clipboard_launcher_no_assistant.icon",
"clipboard_launcher_outer.icon",
"clipboard_search.icon",
"close_button.icon",
"copy.icon",
"dark_theme_color_mode.icon",
"delete.icon",
"desks_new_desk_button.icon",
"dictation_menu.icon",
"dictation_off.icon",
"dictation_off_newui.icon",
"dictation_on.icon",
"dictation_on_newui.icon",
"dogfood.icon",
"folder.icon",
"global_media_controls.icon",
"holding_space.icon",
"hollow_check_circle.icon",
"ime_menu_emoticon.icon",
"ime_menu_microphone.icon",
"ime_menu_on_screen_keyboard.icon",
"ime_menu_write.icon",
"keyboard.icon",
"lock_screen_alert.icon",
"lock_screen_arrow.icon",
"lock_screen_arrow_back.icon",
"lock_screen_backspace.icon",
"lock_screen_caps_lock.icon",
"lock_screen_dropdown.icon",
"lock_screen_fingerprint.icon",
"lock_screen_fingerprint_success.icon",
"lock_screen_password_invisible.icon",
"lock_screen_password_visible.icon",
"lock_screen_smart_card.icon",
"lock_screen_smart_card_failure.icon",
"lock_screen_time_limit_lock.icon",
"lock_screen_time_limit_moon.icon",
"lock_screen_time_limit_timer.icon",
"login_screen_button_dropdown.icon",
"login_screen_enterprise.icon",
"login_screen_menu_dropdown.icon",
"mic.icon",
"muted_microphone.icon",
"network_badge_captive_portal.icon",
"network_badge_off.icon",
"network_badge_roaming.icon",
"network_badge_secure.icon",
"network_badge_technology_1x.icon",
"network_badge_technology_3g.icon",
"network_badge_technology_4g.icon",
"network_badge_technology_edge.icon",
"network_badge_technology_evdo.icon",
"network_badge_technology_gprs.icon",
"network_badge_technology_hspa.icon",
"network_badge_technology_hspa_plus.icon",
"network_badge_technology_lte.icon",
"network_badge_technology_lte_advanced.icon",
"network_badge_vpn.icon",
"network_ethernet.icon",
"network_mobile_not_connected_x.icon",
"network_vpn.icon",
"notification_accessibility.icon",
"notification_accessibility_braille.icon",
"notification_battery_critical.icon",
"notification_battery_fluctuating.icon",
"notification_battery_low.icon",
"notification_bluetooth.icon",
"notification_bluetooth_battery_warning.icon",
"notification_capslock.icon",
"notification_center_all_done.icon",
"notification_center_clear_all.icon",
"notification_center_collapse.icon",
"notification_center_do_not_disturb_off.icon",
"notification_center_do_not_disturb_on.icon",
"notification_center_empty.icon",
"notification_center_settings.icon",
"notification_charging_usb_c.icon",
"notification_chromevox.icon",
"notification_keyboard.icon",
"notification_low_power_charger.icon",
"notification_monitor_warning.icon",
"notification_multi_device_setup.icon",
"notification_screen.icon",
"notification_screenshare.icon",
"notification_sms_sync.icon",
"notification_stylus_battery_warning.icon",
"notification_timer.icon",
"overflow_shelf_left.icon",
"overflow_shelf_right.icon",
"overview_drop_target_plus.icon",
"overview_window_close.icon",
"palette_action_capture_region.icon",
"palette_action_capture_screen.icon",
"palette_action_create_note.icon",
"palette_mode_laser_pointer.icon",
"palette_mode_magnify.icon",
"palette_mode_metalayer.icon",
"palette_tray_icon_capture_region.icon",
"palette_tray_icon_default.icon",
"palette_tray_icon_default_newui.icon",
"palette_tray_icon_laser_pointer.icon",
"palette_tray_icon_magnify.icon",
"palette_tray_icon_metalayer.icon",
"phone_hub_mobile_no_connection.icon",
"phone_hub_mobile_no_sim.icon",
"pin_request_lock.icon",
"pinned.icon",
"privacy_screen.icon",
"send.icon",
"settings.icon",
"shelf_add_person_button.icon",
"shelf_apps_button.icon",
"shelf_back.icon",
"shelf_browse_as_guest_button.icon",
"shelf_cancel_button.icon",
"shelf_globe.icon",
"shelf_keyboard.icon",
"shelf_keyboard_newui.icon",
"shelf_logout.icon",
"shelf_notifications.icon",
"shelf_overflow.icon",
"shelf_overflow_horizontal_dots.icon",
"shelf_overview.icon",
"shelf_position.icon",
"shelf_shutdown_button.icon",
"shelf_sign_out_button.icon",
"shelf_unlock_button.icon",
"switch_access.icon",
"switch_access_back.icon",
"switch_access_close.icon",
"switch_access_copy.icon",
"switch_access_cut.icon",
"switch_access_decrement.icon",
"switch_access_end_text_selection.icon",
"switch_access_increment.icon",
"switch_access_jump_to_beginning_of_text.icon",
"switch_access_jump_to_end_of_text.icon",
"switch_access_keyboard.icon",
"switch_access_move_backward_one_char_of_text.icon",
"switch_access_move_backward_one_word_of_text.icon",
"switch_access_move_cursor.icon",
"switch_access_move_down_one_line_of_text.icon",
"switch_access_move_forward_one_char_of_text.icon",
"switch_access_move_forward_one_word_of_text.icon",
"switch_access_move_up_one_line_of_text.icon",
"switch_access_paste.icon",
"switch_access_scroll_down.icon",
"switch_access_scroll_left.icon",
"switch_access_scroll_right.icon",
"switch_access_scroll_up.icon",
"switch_access_select.icon",
"switch_access_settings.icon",
"switch_access_start_text_selection.icon",
"system_menu_accessibility.icon",
"system_menu_accessibility_auto_click.icon",
"system_menu_accessibility_chromevox.icon",
"system_menu_accessibility_contrast.icon",
"system_menu_accessibility_docked_magnifier.icon",
"system_menu_accessibility_fullscreen_magnifier.icon",
"system_menu_accessibility_select_to_speak.icon",
"system_menu_add_connection.icon",
"system_menu_arrow_back.icon",
"system_menu_audio_input.icon",
"system_menu_audio_output.icon",
"system_menu_bluetooth.icon",
"system_menu_bluetooth_connected.icon",
"system_menu_bluetooth_disabled.icon",
"system_menu_brightness.icon",
"system_menu_business.icon",
"system_menu_caps_lock.icon",
"system_menu_cast.icon",
"system_menu_cast_audio.icon",
"system_menu_cast_audio_group.icon",
"system_menu_cast_enabled.icon",
"system_menu_cast_generic.icon",
"system_menu_cast_message.icon",
"system_menu_computer.icon",
"system_menu_gamepad.icon",
"system_menu_guest.icon",
"system_menu_hdmi.icon",
"system_menu_headset.icon",
"system_menu_help.icon",
"system_menu_info.icon",
"system_menu_keyboard.icon",
"system_menu_keyboard_brightness.icon",
"system_menu_legacy_supervised_user.icon",
"system_menu_lock.icon",
"system_menu_mouse.icon",
"system_menu_new_user.icon",
"system_menu_phone.icon",
"system_menu_power.icon",
"system_menu_rollback.icon",
"system_menu_rotation_lock_auto.icon",
"system_menu_rotation_lock_landscape.icon",
"system_menu_rotation_lock_portrait.icon",
"system_menu_screen_share.icon",
"system_menu_settings.icon",
"system_menu_supervised_user.icon",
"system_menu_tablet.icon",
"system_menu_timer.icon",
"system_menu_tracing.icon",
"system_menu_update.icon",
"system_menu_usb.icon",
"system_menu_videocam.icon",
"system_menu_volume_high.icon",
"system_menu_volume_low.icon",
"system_menu_volume_medium.icon",
"system_menu_volume_mute.icon",
"system_power_button_menu_feedback.icon",
"system_power_button_menu_lock_screen.icon",
"system_power_button_menu_power_off.icon",
"system_power_button_menu_sign_out.icon",
"system_tray_accessibility.icon",
"system_tray_app_badging.icon",
"system_tray_caps_lock.icon",
"system_tray_cast.icon",
"system_tray_do_not_disturb.icon",
"system_tray_managed.icon",
"system_tray_notification_counter_plus.icon",
"system_tray_recording.icon",
"system_tray_rotation_lock_auto.icon",
"system_tray_rotation_lock_locked.icon",
"system_tray_screen_share.icon",
"system_tray_select_to_speak.icon",
"system_tray_select_to_speak_active.icon",
"system_tray_select_to_speak_active_newui.icon",
"system_tray_select_to_speak_newui.icon",
"system_tray_stop.icon",
"system_tray_stop_newui.icon",
"system_tray_supervised_user.icon",
"system_tray_tracing.icon",
"system_tray_update.icon",
"system_tray_volume_mute.icon",
"touch_calibration_complete_check.icon",
"touch_calibration_hand.icon",
"tray_action_new_lock_screen_note.icon",
"unified_menu_accessibility.icon",
"unified_menu_arrow_back.icon",
"unified_menu_battery_alert.icon",
"unified_menu_battery_alert_outline.icon",
"unified_menu_battery_bolt.icon",
"unified_menu_battery_bolt_outline.icon",
"unified_menu_battery_unreliable.icon",
"unified_menu_battery_unreliable_outline.icon",
"unified_menu_battery_x.icon",
"unified_menu_battery_x_outline.icon",
"unified_menu_bluetooth.icon",
"unified_menu_bluetooth_connected.icon",
"unified_menu_brightness.icon",
"unified_menu_cast.icon",
"unified_menu_dark_mode.icon",
"unified_menu_do_not_disturb.icon",
"unified_menu_expand.icon",
"unified_menu_info.icon",
"unified_menu_keyboard.icon",
"unified_menu_keyboard_brightness.icon",
"unified_menu_locale.icon",
"unified_menu_lock.icon",
"unified_menu_managed.icon",
"unified_menu_more.icon",
"unified_menu_nearby_share_not_visible.icon",
"unified_menu_nearby_share_visible.icon",
"unified_menu_night_light.icon",
"unified_menu_power.icon",
"unified_menu_rotation_lock_auto.icon",
"unified_menu_rotation_lock_landscape.icon",
"unified_menu_rotation_lock_portrait.icon",
"unified_menu_settings.icon",
"unified_menu_volume_high.icon",
"unified_menu_volume_low.icon",
"unified_menu_volume_medium.icon",
"unified_menu_volume_mute.icon",
"unified_menu_vpn.icon",
"unified_menu_wifi_no_connection.icon",
"unified_menu_wifi_off.icon",
"unified_network_badge_captive_portal.icon",
"unified_network_badge_secure.icon",
"unified_network_badge_vpn.icon",
"unpinned.icon",
"unrendered_html_placeholder.icon",
"wallpaper.icon",
]
if (is_chrome_branded) {
sources += [
"system_menu_cast_device.icon",
"system_menu_cast_education.icon",
"system_menu_cast_hangout.icon",
"system_menu_cast_meeting.icon",
]
}
}
source_set("vector_icons") {
sources = get_target_outputs(":ash_vector_icons")
deps = [
":ash_vector_icons",
"//base",
"//skia",
"//ui/gfx",
]
}

View File

@ -0,0 +1,22 @@
# Copyright 2018 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.
source_set("search_box") {
sources = [
"search_box_constants.h",
"search_box_view_base.cc",
"search_box_view_base.h",
"search_box_view_delegate.h",
]
deps = [
"//base",
"//skia",
"//ui/base",
"//ui/base/ime",
"//ui/events",
"//ui/strings",
"//ui/views",
]
}

View File

@ -0,0 +1,58 @@
# Copyright 2018 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.
# KSV: Keyboard Shortcut Viewer
source_set("shortcut_viewer") {
sources = [
"keyboard_shortcut_item.cc",
"keyboard_shortcut_item.h",
"keyboard_shortcut_viewer_metadata.cc",
"keyboard_shortcut_viewer_metadata.h",
"ksv_export.h",
"views/bubble_view.cc",
"views/bubble_view.h",
"views/keyboard_shortcut_item_list_view.cc",
"views/keyboard_shortcut_item_list_view.h",
"views/keyboard_shortcut_item_view.cc",
"views/keyboard_shortcut_item_view.h",
"views/keyboard_shortcut_view.cc",
"views/keyboard_shortcut_view.h",
"views/ksv_search_box_view.cc",
"views/ksv_search_box_view.h",
]
defines = [ "KSV_IMPLEMENTATION" ]
deps = [
"//ash",
"//ash/public/cpp",
"//ash/public/cpp/resources:ash_public_unscaled_resources",
"//ash/search_box",
"//ash/shortcut_viewer/strings",
"//ash/shortcut_viewer/vector_icons",
"//cc/paint",
"//ui/accessibility",
"//ui/aura",
"//ui/chromeos/events",
"//ui/events:events_base",
"//ui/events/devices",
"//ui/events/ozone/layout",
"//ui/views",
]
}
source_set("unit_tests") {
testonly = true
sources = [ "views/keyboard_shortcut_view_unittest.cc" ]
deps = [
":shortcut_viewer",
"//ash:test_support",
"//base/test:test_support",
"//testing/gtest",
"//ui/compositor:test_support",
"//ui/events:test_support",
"//ui/events/devices:test_support",
"//ui/views",
]
}

View File

@ -0,0 +1,66 @@
# Copyright 2018 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.
import("//tools/grit/grit_rule.gni")
grit("strings") {
source = "../shortcut_viewer_strings.grd"
outputs = [
"grit/shortcut_viewer_strings.h",
"shortcut_viewer_strings_am.pak",
"shortcut_viewer_strings_ar.pak",
"shortcut_viewer_strings_bg.pak",
"shortcut_viewer_strings_bn.pak",
"shortcut_viewer_strings_ca.pak",
"shortcut_viewer_strings_cs.pak",
"shortcut_viewer_strings_da.pak",
"shortcut_viewer_strings_de.pak",
"shortcut_viewer_strings_el.pak",
"shortcut_viewer_strings_en-GB.pak",
"shortcut_viewer_strings_en-US.pak",
"shortcut_viewer_strings_es-419.pak",
"shortcut_viewer_strings_es.pak",
"shortcut_viewer_strings_et.pak",
"shortcut_viewer_strings_fake-bidi.pak",
"shortcut_viewer_strings_fa.pak",
"shortcut_viewer_strings_fil.pak",
"shortcut_viewer_strings_fi.pak",
"shortcut_viewer_strings_fr.pak",
"shortcut_viewer_strings_gu.pak",
"shortcut_viewer_strings_he.pak",
"shortcut_viewer_strings_hi.pak",
"shortcut_viewer_strings_hr.pak",
"shortcut_viewer_strings_hu.pak",
"shortcut_viewer_strings_id.pak",
"shortcut_viewer_strings_it.pak",
"shortcut_viewer_strings_ja.pak",
"shortcut_viewer_strings_kn.pak",
"shortcut_viewer_strings_ko.pak",
"shortcut_viewer_strings_lt.pak",
"shortcut_viewer_strings_lv.pak",
"shortcut_viewer_strings_ml.pak",
"shortcut_viewer_strings_mr.pak",
"shortcut_viewer_strings_ms.pak",
"shortcut_viewer_strings_nb.pak",
"shortcut_viewer_strings_nl.pak",
"shortcut_viewer_strings_pl.pak",
"shortcut_viewer_strings_pt-BR.pak",
"shortcut_viewer_strings_pt-PT.pak",
"shortcut_viewer_strings_ro.pak",
"shortcut_viewer_strings_ru.pak",
"shortcut_viewer_strings_sk.pak",
"shortcut_viewer_strings_sl.pak",
"shortcut_viewer_strings_sr.pak",
"shortcut_viewer_strings_sv.pak",
"shortcut_viewer_strings_sw.pak",
"shortcut_viewer_strings_ta.pak",
"shortcut_viewer_strings_te.pak",
"shortcut_viewer_strings_th.pak",
"shortcut_viewer_strings_tr.pak",
"shortcut_viewer_strings_uk.pak",
"shortcut_viewer_strings_vi.pak",
"shortcut_viewer_strings_zh-CN.pak",
"shortcut_viewer_strings_zh-TW.pak",
]
}

View File

@ -0,0 +1,41 @@
# Copyright 2018 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.
import("//components/vector_icons/vector_icons.gni")
aggregate_vector_icons2("ksv_vector_icons") {
icon_directory = "."
sources = [
"ksv_arrow_down.icon",
"ksv_arrow_left.icon",
"ksv_arrow_right.icon",
"ksv_arrow_up.icon",
"ksv_brightness_down.icon",
"ksv_brightness_up.icon",
"ksv_browser_back.icon",
"ksv_browser_forward.icon",
"ksv_fullscreen.icon",
"ksv_mute.icon",
"ksv_overview.icon",
"ksv_privacy_screen_toggle.icon",
"ksv_reload.icon",
"ksv_search_back.icon",
"ksv_search_bar.icon",
"ksv_search_close.icon",
"ksv_search_no_result.icon",
"ksv_separator_plus.icon",
"ksv_volume_down.icon",
"ksv_volume_up.icon",
]
}
source_set("vector_icons") {
sources = get_target_outputs(":ksv_vector_icons")
deps = [
":ksv_vector_icons",
"//skia",
]
}

109
src/ash/strings/BUILD.gn Normal file
View File

@ -0,0 +1,109 @@
# Copyright 2014 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.
import("//tools/grit/grit_rule.gni")
import("//tools/grit/repack.gni")
assert(is_chromeos)
grit("strings") {
source = "../ash_strings.grd"
defines = [ "is_chrome_branded=$is_chrome_branded" ]
outputs = [
"grit/ash_strings.h",
"ash_strings_am.pak",
"ash_strings_ar.pak",
"ash_strings_bg.pak",
"ash_strings_bn.pak",
"ash_strings_ca.pak",
"ash_strings_cs.pak",
"ash_strings_da.pak",
"ash_strings_de.pak",
"ash_strings_el.pak",
"ash_strings_en-GB.pak",
"ash_strings_en-US.pak",
"ash_strings_es.pak",
"ash_strings_es-419.pak",
"ash_strings_et.pak",
"ash_strings_fa.pak",
"ash_strings_fake-bidi.pak",
"ash_strings_fi.pak",
"ash_strings_fil.pak",
"ash_strings_fr.pak",
"ash_strings_gu.pak",
"ash_strings_he.pak",
"ash_strings_hi.pak",
"ash_strings_hr.pak",
"ash_strings_hu.pak",
"ash_strings_id.pak",
"ash_strings_it.pak",
"ash_strings_ja.pak",
"ash_strings_kn.pak",
"ash_strings_ko.pak",
"ash_strings_lt.pak",
"ash_strings_lv.pak",
"ash_strings_ml.pak",
"ash_strings_mr.pak",
"ash_strings_ms.pak",
"ash_strings_nl.pak",
"ash_strings_nb.pak",
"ash_strings_pl.pak",
"ash_strings_pt-BR.pak",
"ash_strings_pt-PT.pak",
"ash_strings_ro.pak",
"ash_strings_ru.pak",
"ash_strings_sk.pak",
"ash_strings_sl.pak",
"ash_strings_sr.pak",
"ash_strings_sv.pak",
"ash_strings_sw.pak",
"ash_strings_ta.pak",
"ash_strings_te.pak",
"ash_strings_th.pak",
"ash_strings_tr.pak",
"ash_strings_uk.pak",
"ash_strings_vi.pak",
"ash_strings_zh-CN.pak",
"ash_strings_zh-TW.pak",
]
}
# Creates locale-specific pak files with strings needed for ash_unittests, etc.
template("repack_one_locale_ash") {
locale = invoker.locale
output = invoker.output
repack(target_name) {
# Each input pak file should also have a deps line for completeness.
sources = [
"$root_gen_dir/ash/shortcut_viewer/strings/shortcut_viewer_strings_${locale}.pak",
"$root_gen_dir/ash/strings/ash_strings_${locale}.pak",
"$root_gen_dir/chromeos/strings/chromeos_strings_${locale}.pak",
"$root_gen_dir/components/strings/components_strings_${locale}.pak",
"$root_gen_dir/device/bluetooth/strings/bluetooth_strings_${locale}.pak",
"$root_gen_dir/ui/chromeos/strings/ui_chromeos_strings_${locale}.pak",
"$root_gen_dir/ui/strings/app_locale_settings_${locale}.pak",
"$root_gen_dir/ui/strings/ui_strings_${locale}.pak",
]
deps = [
"//ash/shortcut_viewer/strings",
"//ash/strings",
"//chromeos/strings",
"//components/strings",
"//device/bluetooth/strings",
"//ui/chromeos/strings",
"//ui/strings:app_locale_settings",
"//ui/strings:ui_strings",
]
}
}
# Creates a pak file containing en-US strings for ash_unittests, etc.
repack_one_locale_ash("ash_test_strings") {
output = "$root_build_dir/ash_test_strings.pak"
locale = "en-US"
}

View File

@ -0,0 +1,9 @@
# Copyright 2020 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.
import("//third_party/protobuf/proto_library.gni")
proto_library("user_settings_event_proto") {
sources = [ "user_settings_event.proto" ]
}

4091
src/base/BUILD.gn Normal file

File diff suppressed because it is too large Load Diff

22
src/base/DEPS Normal file
View File

@ -0,0 +1,22 @@
include_rules = [
"+third_party/ashmem",
"+third_party/apple_apsl",
"+third_party/boringssl/src/include",
"+third_party/ced",
"+third_party/libunwindstack/src/libunwindstack/include",
"+third_party/lss",
"+third_party/modp_b64",
"+third_party/perfetto/include",
"+third_party/perfetto/protos/perfetto",
"+third_party/tcmalloc",
# These are implicitly brought in from the root, and we don't want them.
"-ipc",
"-url",
# ICU dependendencies must be separate from the rest of base.
"-i18n",
# //base/util can use //base but not vice versa.
"-util",
]

38
src/base/OWNERS Normal file
View File

@ -0,0 +1,38 @@
# See //base/README.md to find qualification for being an owner.
ajwong@chromium.org
danakj@chromium.org
dcheng@chromium.org
fdoray@chromium.org
gab@chromium.org
jdoerrie@chromium.org
kylechar@chromium.org
mark@chromium.org
thakis@chromium.org
thestig@chromium.org
wez@chromium.org
# For Android-specific changes:
per-file *android*=file://base/android/OWNERS
per-file BUILD.gn=file://base/android/OWNERS
# For Fuchsia-specific changes:
per-file *_fuchsia*=file://build/fuchsia/OWNERS
# For Windows-specific changes:
per-file *_win*=file://base/win/OWNERS
per-file callback_list*=pkasting@chromium.org
per-file feature_list*=asvitkine@chromium.org
per-file feature_list*=isherman@chromium.org
# Restricted since rand_util.h also backs the cryptographically secure RNG.
per-file rand_util*=set noparent
per-file rand_util*=file://ipc/SECURITY_OWNERS
per-file safe_numerics_unittest.cc=file://base/numerics/OWNERS
# For TCMalloc tests:
per-file security_unittest.cc=jln@chromium.org
# COMPONENT: Internals>Core

99
src/base/PRESUBMIT.py Normal file
View File

@ -0,0 +1,99 @@
# Copyright (c) 2012 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.
"""Chromium presubmit script for src/base.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details on the presubmit API built into depot_tools.
"""
def _CheckNoInterfacesInBase(input_api, output_api):
"""Checks to make sure no files in libbase.a have |@interface|."""
pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE)
files = []
for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
if (f.LocalPath().startswith('base/') and
not "/ios/" in f.LocalPath() and
not "/test/" in f.LocalPath() and
not f.LocalPath().endswith('.java') and
not f.LocalPath().endswith('_unittest.mm') and
not f.LocalPath().endswith('mac/sdk_forward_declarations.h')):
contents = input_api.ReadFile(f)
if pattern.search(contents):
files.append(f)
if len(files):
return [ output_api.PresubmitError(
'Objective-C interfaces or categories are forbidden in libbase. ' +
'See http://groups.google.com/a/chromium.org/group/chromium-dev/' +
'browse_thread/thread/efb28c10435987fd',
files) ]
return []
def _CheckNoTraceEventInclude(input_api, output_api):
"""Verify that //base includes base_tracing.h instead of trace event headers.
Checks that files outside trace event implementation include the
base_tracing.h header instead of specific trace event implementation headers
to maintain compatibility with the gn flag "enable_base_tracing = false".
"""
discouraged_includes = [
r'^#include "base/trace_event/(?!base_tracing\.h)',
]
files_to_check = [
r".*\.(h|cc|mm)$",
]
files_to_skip = [
r".*[\\/]test[\\/].*",
r".*[\\/]trace_event[\\/].*",
r".*[\\/]tracing[\\/].*",
]
no_presubmit = r"// no-presubmit-check"
def FilterFile(affected_file):
return input_api.FilterSourceFile(
affected_file,
files_to_check=files_to_check,
files_to_skip=files_to_skip)
locations = []
for f in input_api.AffectedSourceFiles(FilterFile):
for line_num, line in f.ChangedContents():
for include in discouraged_includes:
if (input_api.re.search(include, line) and
not input_api.re.search(no_presubmit, line)):
locations.append(" %s:%d" % (f.LocalPath(), line_num))
break
if locations:
return [ output_api.PresubmitError(
'Base code should include "base/trace_event/base_tracing.h" instead\n' +
'of trace_event implementation headers. If you need to include an\n' +
'implementation header, verify that base_unittests still passes\n' +
'with gn arg "enable_base_tracing = false" and add\n' +
'"// no-presubmit-check" after the include. \n' +
'\n'.join(locations)) ]
return []
def _CommonChecks(input_api, output_api):
"""Checks common to both upload and commit."""
results = []
results.extend(_CheckNoInterfacesInBase(input_api, output_api))
results.extend(_CheckNoTraceEventInclude(input_api, output_api))
return results
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
return results
def CheckChangeOnCommit(input_api, output_api):
results = []
results.extend(_CommonChecks(input_api, output_api))
return results

81
src/base/README.md Normal file
View File

@ -0,0 +1,81 @@
# What is this
Contains a written down set of principles and other information on //base.
Please add to it!
## About //base:
Chromium is a very mature project. Most things that are generally useful are
already here and things not here aren't generally useful.
The bar for adding stuff to base is that it must have demonstrated wide
applicability. Prefer to add things closer to where they're used (i.e. "not
base"), and pull into base only when needed. In a project our size,
sometimes even duplication is OK and inevitable.
Adding a new logging macro `DPVELOG_NE` is not more clear than just
writing the stuff you want to log in a regular logging statement, even
if it makes your calling code longer. Just add it to your own code.
If the code in question does not need to be used inside base, but will have
multiple consumers across the codebase, consider placing it in a new directory
under components/ instead.
base is written for the Chromium project and is not intended to be used
outside it. Using base outside of src.git is explicitly not supported,
and base makes no guarantees about API (or even ABI) stability (like all
other code in Chromium). New code that depends on base/ must be in
src.git. Code that's not in src.git but pulled in through DEPS (for
example, v8) cannot use base.
## Qualifications for being in //base OWNERS
* interest and ability to learn low level/high detail/complex c++ stuff
* inclination to always ask why and understand everything (including external
interactions like win32) rather than just hoping the author did it right
* mentorship/experience
* demonstrated good judgement (esp with regards to public APIs) over a length
of time
Owners are added when a contributor has shown the above qualifications and
when they express interest. There isn't an upper bound on the number of OWNERS.
## Design and naming
* Be sure to use the base namespace.
* STL-like constructs should adhere as closely to STL as possible. Functions
and behaviors not present in STL should only be added when they are related
to the specific data structure implemented by the container.
* For STL-like constructs our policy is that they should use STL-like naming
even when it may conflict with the style guide. So functions and class names
should be lower case with underscores. Non-STL-like classes and functions
should use Google naming.
## Performance testing
Since the primitives provided by //base are used very widely, it is important to
ensure they scale to the necessary workloads and perform well under all
supported platforms. The `base_perftests` target is a suite of
synthetic microbenchmarks that measure performance in various scenarios:
* BasicPostTaskPerfTest: Exercises MessageLoopTaskRunner's multi-threaded
queue in isolation.
* ConditionVariablePerfTest: Measures thread switching cost of condition
variables.
* IntegratedPostTaskPerfTest: Exercises the full MessageLoop/RunLoop
machinery.
* JSONPerfTest: Tests JSONWriter and JSONReader performance.
* MessageLoopPerfTest: Measures the speed of task posting in various
configurations.
* ObserverListPerfTest: Exercises adding, removing and signalling observers.
* PthreadEventPerfTest: Establishes the baseline thread switching cost using
pthreads.
* ScheduleWorkTest: Measures the overhead of MessagePump::ScheduleWork.
* SequenceManagerPerfTest: Benchmarks SequenceManager scheduling with various
underlying task runners.
* TaskObserverPerfTest: Measures the incremental cost of adding task
observers.
* TaskPerfTest: Checks the cost of posting tasks between threads.
* WaitableEvent{Thread,}PerfTest: Measures waitable events in single and
multithreaded scenarios.
Regressions in these benchmarks can generally by caused by 1) operating system
changes, 2) compiler version or flag changes or 3) changes in //base code
itself.

14
src/base/SECURITY_OWNERS Normal file
View File

@ -0,0 +1,14 @@
# Changes to code that runs at high privilege and which has a high risk of
# memory corruption, such as parsers for complex inputs, require a security
# review to avoid introducing sandbox escapes.
#
# Although this file is in base/, it may apply to more than just base, OWNERS
# files outside of base may also include this file.
#
# Security team: If you are uncomfortable reviewing a particular bit of code
# yourself, don't hesitate to seek help from another security team member!
# Nobody knows everything, and the only way to learn is from experience.
dcheng@chromium.org
palmer@chromium.org
rsesek@chromium.org
tsepez@chromium.org

311
src/base/allocator/BUILD.gn Normal file
View File

@ -0,0 +1,311 @@
# Copyright (c) 2013 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.
import("//base/allocator/allocator.gni")
import("//build/buildflag_header.gni")
import("//build/config/compiler/compiler.gni")
# This file depends on the legacy global sources assignment filter. It should
# be converted to check target platform before assigning source files to the
# sources variable. Remove this import and set_sources_assignment_filter call
# when the file has been converted. See https://crbug.com/1018739 for details.
import("//build/config/deprecated_default_sources_assignment_filter.gni")
set_sources_assignment_filter(deprecated_default_sources_assignment_filter)
declare_args() {
# Provide a way to force disable debugallocation in Debug builds,
# e.g. for profiling (it's more rare to profile Debug builds,
# but people sometimes need to do that).
enable_debugallocation = is_debug
# Provide a way to build tcmalloc with a low memory footprint.
use_tcmalloc_small_but_slow = false
}
# This "allocator" meta-target will forward to the default allocator according
# to the build settings.
group("allocator") {
public_deps = []
deps = []
if (use_allocator == "tcmalloc") {
deps += [ ":tcmalloc" ]
}
}
config("tcmalloc_flags") {
defines = [
"TCMALLOC_USE_DOUBLYLINKED_FREELIST",
"TCMALLOC_DISABLE_HUGE_ALLOCATIONS",
]
if (enable_debugallocation) {
defines += [
# Use debugallocation for Debug builds to catch problems early
# and cleanly, http://crbug.com/30715 .
"TCMALLOC_FOR_DEBUGALLOCATION",
]
}
if (use_allocator_shim) {
defines += [ "TCMALLOC_DONT_REPLACE_SYSTEM_ALLOC" ]
}
if (use_tcmalloc_small_but_slow) {
defines += [ "TCMALLOC_SMALL_BUT_SLOW" ]
}
if (is_clang) {
cflags = [
# tcmalloc initializes some fields in the wrong order.
"-Wno-reorder",
# tcmalloc contains some unused local template specializations.
"-Wno-unused-function",
# tcmalloc uses COMPILE_ASSERT without static_assert but with typedefs.
"-Wno-unused-local-typedefs",
# for magic2_ in debugallocation.cc (only built in Debug builds) typedefs.
"-Wno-unused-private-field",
]
} else {
cflags = []
}
if (is_linux || is_chromeos || is_android) {
# We enable all warnings by default, but upstream disables a few.
# Keep "-Wno-*" flags in sync with upstream by comparing against:
# http://code.google.com/p/google-perftools/source/browse/trunk/Makefile.am
cflags += [
"-Wno-sign-compare",
"-Wno-unused-result",
]
}
}
if (use_allocator == "tcmalloc") {
# tcmalloc currently won't compile on Android.
source_set("tcmalloc") {
tcmalloc_dir = "//third_party/tcmalloc/chromium"
# Don't check tcmalloc's includes. These files include various files like
# base/foo.h and they actually refer to tcmalloc's forked copy of base
# rather than the regular one, which confuses the header checker.
check_includes = false
sources = [
# Generated for our configuration from tcmalloc's build
# and checked in.
"$tcmalloc_dir/src/config.h",
"$tcmalloc_dir/src/config_android.h",
"$tcmalloc_dir/src/config_linux.h",
"$tcmalloc_dir/src/config_win.h",
# tcmalloc native and forked files.
"$tcmalloc_dir/src/base/abort.cc",
"$tcmalloc_dir/src/base/abort.h",
"$tcmalloc_dir/src/base/arm_instruction_set_select.h",
"$tcmalloc_dir/src/base/atomicops-internals-arm-generic.h",
"$tcmalloc_dir/src/base/atomicops-internals-arm-v6plus.h",
"$tcmalloc_dir/src/base/atomicops-internals-linuxppc.h",
"$tcmalloc_dir/src/base/atomicops-internals-macosx.h",
"$tcmalloc_dir/src/base/atomicops-internals-windows.h",
"$tcmalloc_dir/src/base/atomicops-internals-x86.cc",
"$tcmalloc_dir/src/base/atomicops-internals-x86.h",
"$tcmalloc_dir/src/base/atomicops.h",
"$tcmalloc_dir/src/base/commandlineflags.h",
# We don't list dynamic_annotations.c since its copy is already
# present in the dynamic_annotations target.
"$tcmalloc_dir/src/base/elf_mem_image.cc",
"$tcmalloc_dir/src/base/elf_mem_image.h",
"$tcmalloc_dir/src/base/linuxthreads.cc",
"$tcmalloc_dir/src/base/linuxthreads.h",
"$tcmalloc_dir/src/base/logging.cc",
"$tcmalloc_dir/src/base/logging.h",
"$tcmalloc_dir/src/base/low_level_alloc.cc",
"$tcmalloc_dir/src/base/low_level_alloc.h",
"$tcmalloc_dir/src/base/spinlock.cc",
"$tcmalloc_dir/src/base/spinlock.h",
"$tcmalloc_dir/src/base/spinlock_internal.cc",
"$tcmalloc_dir/src/base/spinlock_internal.h",
"$tcmalloc_dir/src/base/sysinfo.cc",
"$tcmalloc_dir/src/base/sysinfo.h",
"$tcmalloc_dir/src/base/vdso_support.cc",
"$tcmalloc_dir/src/base/vdso_support.h",
"$tcmalloc_dir/src/central_freelist.cc",
"$tcmalloc_dir/src/central_freelist.h",
"$tcmalloc_dir/src/common.cc",
"$tcmalloc_dir/src/common.h",
# #included by debugallocation_shim.cc
#"$tcmalloc_dir/src/debugallocation.cc",
"$tcmalloc_dir/src/fake_stacktrace_scope.cc",
"$tcmalloc_dir/src/free_list.cc",
"$tcmalloc_dir/src/free_list.h",
"$tcmalloc_dir/src/gperftools/heap-profiler.h",
"$tcmalloc_dir/src/gperftools/malloc_extension.h",
"$tcmalloc_dir/src/gperftools/malloc_hook.h",
"$tcmalloc_dir/src/gperftools/stacktrace.h",
"$tcmalloc_dir/src/internal_logging.cc",
"$tcmalloc_dir/src/internal_logging.h",
"$tcmalloc_dir/src/linked_list.h",
"$tcmalloc_dir/src/malloc_extension.cc",
"$tcmalloc_dir/src/malloc_hook-inl.h",
"$tcmalloc_dir/src/malloc_hook.cc",
"$tcmalloc_dir/src/maybe_emergency_malloc.h",
"$tcmalloc_dir/src/maybe_threads.cc",
"$tcmalloc_dir/src/maybe_threads.h",
"$tcmalloc_dir/src/page_heap.cc",
"$tcmalloc_dir/src/page_heap.h",
"$tcmalloc_dir/src/raw_printer.cc",
"$tcmalloc_dir/src/raw_printer.h",
"$tcmalloc_dir/src/sampler.cc",
"$tcmalloc_dir/src/sampler.h",
"$tcmalloc_dir/src/span.cc",
"$tcmalloc_dir/src/span.h",
"$tcmalloc_dir/src/stack_trace_table.cc",
"$tcmalloc_dir/src/stack_trace_table.h",
"$tcmalloc_dir/src/stacktrace.cc",
"$tcmalloc_dir/src/static_vars.cc",
"$tcmalloc_dir/src/static_vars.h",
"$tcmalloc_dir/src/symbolize.cc",
"$tcmalloc_dir/src/symbolize.h",
"$tcmalloc_dir/src/system-alloc.cc",
"$tcmalloc_dir/src/system-alloc.h",
# #included by debugallocation_shim.cc
#"$tcmalloc_dir/src/tcmalloc.cc",
#"$tcmalloc_dir/src/tcmalloc.h",
"$tcmalloc_dir/src/thread_cache.cc",
"$tcmalloc_dir/src/thread_cache.h",
"$tcmalloc_dir/src/windows/port.cc",
"$tcmalloc_dir/src/windows/port.h",
"debugallocation_shim.cc",
# These are both #included by allocator_shim for maximal linking.
#"generic_allocators.cc",
#"win_allocator.cc",
]
# Not included on mips64el.
if (current_cpu == "mips64el") {
sources -= [
"$tcmalloc_dir/src/base/linuxthreads.cc",
"$tcmalloc_dir/src/base/linuxthreads.h",
]
}
# Disable the heap checker in tcmalloc.
defines = [ "NO_HEAP_CHECK" ]
include_dirs = [
".",
"$tcmalloc_dir/src/base",
"$tcmalloc_dir/src",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
":tcmalloc_flags",
]
# Thumb mode disabled due to bug in clang integrated assembler
# TODO(https://llvm.org/bugs/show_bug.cgi?id=31058)
configs -= [ "//build/config/compiler:compiler_arm_thumb" ]
configs += [ "//build/config/compiler:compiler_arm" ]
# TODO(crbug.com/633719) Make tcmalloc work with AFDO on GCC if possible.
if (!is_clang) {
configs -= [ "//build/config/compiler:afdo" ]
}
deps = [ ":buildflags" ]
if (enable_profiling) {
sources += [
"$tcmalloc_dir/src/base/thread_lister.c",
"$tcmalloc_dir/src/base/thread_lister.h",
"$tcmalloc_dir/src/heap-profile-table.cc",
"$tcmalloc_dir/src/heap-profile-table.h",
"$tcmalloc_dir/src/heap-profiler.cc",
"$tcmalloc_dir/src/memory_region_map.cc",
"$tcmalloc_dir/src/memory_region_map.h",
"$tcmalloc_dir/src/profile-handler.cc",
"$tcmalloc_dir/src/profile-handler.h",
"$tcmalloc_dir/src/profiledata.cc",
"$tcmalloc_dir/src/profiledata.h",
"$tcmalloc_dir/src/profiler.cc",
]
defines += [ "ENABLE_PROFILING=1" ]
}
if (is_linux || is_chromeos || is_android) {
sources -= [
"$tcmalloc_dir/src/system-alloc.h",
"$tcmalloc_dir/src/windows/port.cc",
"$tcmalloc_dir/src/windows/port.h",
]
# Compiling tcmalloc with -fvisibility=default is only necessary when
# not using the allocator shim, which provides the correct visibility
# annotations for those symbols which need to be exported (see
# //base/allocator/allocator_shim_override_glibc_weak_symbols.h and
# //base/allocator/allocator_shim_internals.h for the definition of
# SHIM_ALWAYS_EXPORT).
if (!use_allocator_shim) {
configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
configs += [ "//build/config/gcc:symbol_visibility_default" ]
}
ldflags = [
# Don't let linker rip this symbol out, otherwise the heap&cpu
# profilers will not initialize properly on startup.
"-Wl,-uIsHeapProfilerRunning,-uProfilerStart",
# Do the same for heap leak checker.
"-Wl,-u_Z21InitialMallocHook_NewPKvj,-u_Z22InitialMallocHook_MMapPKvS0_jiiix,-u_Z22InitialMallocHook_SbrkPKvi",
"-Wl,-u_Z21InitialMallocHook_NewPKvm,-u_Z22InitialMallocHook_MMapPKvS0_miiil,-u_Z22InitialMallocHook_SbrkPKvl",
"-Wl,-u_ZN15HeapLeakChecker12IgnoreObjectEPKv,-u_ZN15HeapLeakChecker14UnIgnoreObjectEPKv",
]
}
# Make sure the allocation library is optimized as much as possible when
# we"re in release mode.
if (!is_debug) {
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
}
deps += [ "//base/third_party/dynamic_annotations" ]
}
} # use_allocator == "tcmalloc"
buildflag_header("buildflags") {
header = "buildflags.h"
_use_partition_alloc = use_allocator == "partition"
_use_tcmalloc = use_allocator == "tcmalloc"
flags = [
"USE_ALLOCATOR_SHIM=$use_allocator_shim",
"USE_TCMALLOC=$_use_tcmalloc",
"USE_PARTITION_ALLOC_AS_MALLOC=$_use_partition_alloc",
]
}
# Used to shim malloc symbols on Android. see //base/allocator/README.md.
config("wrap_malloc_symbols") {
ldflags = [
"-Wl,-wrap,calloc",
"-Wl,-wrap,free",
"-Wl,-wrap,malloc",
"-Wl,-wrap,memalign",
"-Wl,-wrap,posix_memalign",
"-Wl,-wrap,pvalloc",
"-Wl,-wrap,realloc",
"-Wl,-wrap,valloc",
# <string.h> functions
"-Wl,-wrap,strdup",
"-Wl,-wrap,strndup",
]
}

View File

@ -0,0 +1,4 @@
primiano@chromium.org
wfh@chromium.org
# COMPONENT: Internals

View File

@ -0,0 +1,188 @@
This document describes how malloc / new calls are routed in the various Chrome
platforms.
Bare in mind that the chromium codebase does not always just use `malloc()`.
Some examples:
- Large parts of the renderer (Blink) use two home-brewed allocators,
PartitionAlloc and BlinkGC (Oilpan).
- Some subsystems, such as the V8 JavaScript engine, handle memory management
autonomously.
- Various parts of the codebase use abstractions such as `SharedMemory` or
`DiscardableMemory` which, similarly to the above, have their own page-level
memory management.
Background
----------
The `allocator` target defines at compile-time the platform-specific choice of
the allocator and extra-hooks which services calls to malloc/new. The relevant
build-time flags involved are `use_allocator` and `use_allocator_shim`.
The default choices are as follows:
**Windows**
`use_allocator: winheap`, the default Windows heap.
Additionally, `static_library` (i.e. non-component) builds have a shim
layer wrapping malloc/new, which is controlled by `use_allocator_shim`.
The shim layer provides extra security features, such as preventing large
allocations that can hit signed vs. unsigned bugs in third_party code.
**Linux Desktop / CrOS**
`use_allocator: tcmalloc`, a forked copy of tcmalloc which resides in
`third_party/tcmalloc/chromium`. Setting `use_allocator: none` causes the build
to fall back to the system (Glibc) symbols.
**Android**
`use_allocator: none`, always use the allocator symbols coming from Android's
libc (Bionic). As it is developed as part of the OS, it is considered to be
optimized for small devices and more memory-efficient than other choices.
The actual implementation backing malloc symbols in Bionic is up to the board
config and can vary (typically *dlmalloc* or *jemalloc* on most Nexus devices).
**Mac/iOS**
`use_allocator: none`, we always use the system's allocator implementation.
In addition, when building for `asan` / `msan` both the allocator and the shim
layer are disabled.
Layering and build deps
-----------------------
The `allocator` target provides both the source files for tcmalloc (where
applicable) and the linker flags required for the Windows shim layer.
The `base` target is (almost) the only one depending on `allocator`. No other
targets should depend on it, with the exception of the very few executables /
dynamic libraries that don't depend, either directly or indirectly, on `base`
within the scope of a linker unit.
More importantly, **no other place outside of `/base` should depend on the
specific allocator** (e.g., directly include `third_party/tcmalloc`).
If such a functional dependency is required that should be achieved using
abstractions in `base` (see `/base/allocator/allocator_extension.h` and
`/base/memory/`)
**Why `base` depends on `allocator`?**
Because it needs to provide services that depend on the actual allocator
implementation. In the past `base` used to pretend to be allocator-agnostic
and get the dependencies injected by other layers. This ended up being an
inconsistent mess.
See the [allocator cleanup doc][url-allocator-cleanup] for more context.
Linker unit targets (executables and shared libraries) that depend in some way
on `base` (most of the targets in the codebase) get automatically the correct
set of linker flags to pull in tcmalloc or the Windows shim-layer.
Source code
-----------
This directory contains just the allocator (i.e. shim) layer that switches
between the different underlying memory allocation implementations.
The tcmalloc library originates outside of Chromium and exists in
`../../third_party/tcmalloc` (currently, the actual location is defined in the
allocator.gyp file). The third party sources use a vendor-branch SCM pattern to
track Chromium-specific changes independently from upstream changes.
The general intent is to push local changes upstream so that over
time we no longer need any forked files.
Unified allocator shim
----------------------
On most platforms, Chrome overrides the malloc / operator new symbols (and
corresponding free / delete and other variants). This is to enforce security
checks and lately to enable the
[memory-infra heap profiler][url-memory-infra-heap-profiler].
Historically each platform had its special logic for defining the allocator
symbols in different places of the codebase. The unified allocator shim is
a project aimed to unify the symbol definition and allocator routing logic in
a central place.
- Full documentation: [Allocator shim design doc][url-allocator-shim].
- Current state: Available and enabled by default on Android, CrOS, Linux,
Mac OS and Windows.
- Tracking bug: [https://crbug.com/550886][crbug.com/550886].
- Build-time flag: `use_allocator_shim`.
**Overview of the unified allocator shim**
The allocator shim consists of three stages:
```
+-------------------------+ +-----------------------+ +----------------+
| malloc & friends | -> | shim layer | -> | Routing to |
| symbols definition | | implementation | | allocator |
+-------------------------+ +-----------------------+ +----------------+
| - libc symbols (malloc, | | - Security checks | | - tcmalloc |
| calloc, free, ...) | | - Chain of dispatchers| | - glibc |
| - C++ symbols (operator | | that can intercept | | - Android |
| new, delete, ...) | | and override | | bionic |
| - glibc weak symbols | | allocations | | - WinHeap |
| (__libc_malloc, ...) | +-----------------------+ +----------------+
+-------------------------+
```
**1. malloc symbols definition**
This stage takes care of overriding the symbols `malloc`, `free`,
`operator new`, `operator delete` and friends and routing those calls inside the
allocator shim (next point).
This is taken care of by the headers in `allocator_shim_override_*`.
*On Windows*: Windows' UCRT (Universal C Runtime) exports weak symbols, that we
can override in `allocator_shim_override_ucr_symbols_win.h`.
*On Linux/CrOS*: the allocator symbols are defined as exported global symbols
in `allocator_shim_override_libc_symbols.h` (for `malloc`, `free` and friends)
and in `allocator_shim_override_cpp_symbols.h` (for `operator new`,
`operator delete` and friends).
This enables proper interposition of malloc symbols referenced by the main
executable and any third party libraries. Symbol resolution on Linux is a breadth first search that starts from the root link unit, that is the executable
(see EXECUTABLE AND LINKABLE FORMAT (ELF) - Portable Formats Specification).
Additionally, when tcmalloc is the default allocator, some extra glibc symbols
are also defined in `allocator_shim_override_glibc_weak_symbols.h`, for subtle
reasons explained in that file.
The Linux/CrOS shim was introduced by
[crrev.com/1675143004](https://crrev.com/1675143004).
*On Android*: load-time symbol interposition (unlike the Linux/CrOS case) is not
possible. This is because Android processes are `fork()`-ed from the Android
zygote, which pre-loads libc.so and only later native code gets loaded via
`dlopen()` (symbols from `dlopen()`-ed libraries get a different resolution
scope).
In this case, the approach instead of wrapping symbol resolution at link time
(i.e. during the build), via the `--Wl,-wrap,malloc` linker flag.
The use of this wrapping flag causes:
- All references to allocator symbols in the Chrome codebase to be rewritten as
references to `__wrap_malloc` and friends. The `__wrap_malloc` symbols are
defined in the `allocator_shim_override_linker_wrapped_symbols.h` and
route allocator calls inside the shim layer.
- The reference to the original `malloc` symbols (which typically is defined by
the system's libc.so) are accessible via the special `__real_malloc` and
friends symbols (which will be relocated, at load time, against `malloc`).
In summary, this approach is transparent to the dynamic loader, which still sees
undefined symbol references to malloc symbols.
These symbols will be resolved against libc.so as usual.
More details in [crrev.com/1719433002](https://crrev.com/1719433002).
**2. Shim layer implementation**
This stage contains the actual shim implementation. This consists of:
- A singly linked list of dispatchers (structs with function pointers to `malloc`-like functions). Dispatchers can be dynamically inserted at runtime
(using the `InsertAllocatorDispatch` API). They can intercept and override
allocator calls.
- The security checks (suicide on malloc-failure via `std::new_handler`, etc).
This happens inside `allocator_shim.cc`
**3. Final allocator routing**
The final element of the aforementioned dispatcher chain is statically defined
at build time and ultimately routes the allocator calls to the actual allocator
(as described in the *Background* section above). This is taken care of by the
headers in `allocator_shim_default_dispatch_to_*` files.
Related links
-------------
- [Unified allocator shim doc - Feb 2016][url-allocator-shim]
- [Allocator cleanup doc - Jan 2016][url-allocator-cleanup]
- [Proposal to use PartitionAlloc as default allocator](https://crbug.com/339604)
- [Memory-Infra: Tools to profile memory usage in Chrome](/docs/memory-infra/README.md)
[url-allocator-cleanup]: https://docs.google.com/document/d/1V77Kgp_4tfaaWPEZVxNevoD02wXiatnAv7Ssgr0hmjg/edit?usp=sharing
[url-memory-infra-heap-profiler]: /docs/memory-infra/heap_profiler.md
[url-allocator-shim]: https://docs.google.com/document/d/1yKlO1AO4XjpDad9rjcBOI15EKdAGsuGO_IeZy0g0kxo/edit?usp=sharing

View File

@ -0,0 +1,77 @@
# 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.
import("//build/config/chromecast_build.gni")
import("//build/config/sanitizers/sanitizers.gni")
# Temporarily disable tcmalloc on arm64 linux to get rid of compilation errors.
if (is_android || is_apple || is_asan || is_lsan || is_tsan || is_msan ||
is_win || is_fuchsia ||
((is_linux || is_chromeos) && target_cpu == "arm64") ||
(is_cast_audio_only && target_cpu == "arm")) {
_default_allocator = "none"
} else {
_default_allocator = "tcmalloc"
}
# The debug CRT on Windows has some debug features that are incompatible with
# the shim. NaCl in particular does seem to link some binaries statically
# against the debug CRT with "is_nacl=false".
if ((is_linux || is_chromeos || is_android || is_apple ||
(is_win && !is_component_build && !is_debug)) && !is_asan && !is_hwasan &&
!is_lsan && !is_tsan && !is_msan) {
_default_use_allocator_shim = true
} else {
_default_use_allocator_shim = false
}
declare_args() {
# Memory allocator to use. Set to "none" to use default allocator.
use_allocator = _default_allocator
# Causes all the allocations to be routed via allocator_shim.cc.
use_allocator_shim = _default_use_allocator_shim
# Whether PartitionAlloc should be available for use or not.
# true makes PartitionAlloc linked to the executable or shared library and
# makes it available for use, but it doesn't mean that the default allocator
# is PartitionAlloc. PartitionAlloc may or may not be the default allocator.
#
# |use_allocator = "partition"| makes PartitionAlloc the default allocator
# but it's effective only when |use_partition_alloc = true|.
#
# TODO(lizeb, yukishiino): Determine if |use_partition_alloc| is necessary or
# not, and redesign or remove the flag accordingly. We may want to assert a
# possible conflict between |use_allocator = "partition"| and
# |use_partition_alloc = true| rather than prioritizing use_partition_alloc.
use_partition_alloc = !is_ios # Never use PartitionAlloc on iOS.
}
if (!use_partition_alloc && use_allocator == "partition") {
# If there is a conflict, prioritize |use_partition_alloc| over
# |use_allocator|.
use_allocator = "none"
}
assert(use_allocator == "none" || use_allocator == "tcmalloc" ||
use_allocator == "partition")
# Don't ship this configuration, not ready yet.
assert(!(use_allocator == "partition" && is_official_build))
assert(!is_win || use_allocator != "tcmalloc",
"Tcmalloc doesn't work on Windows.")
assert(!is_mac || use_allocator != "tcmalloc",
"Tcmalloc doesn't work on macOS.")
assert(!is_ios || use_allocator != "tcmalloc", "Tcmalloc doesn't work on iOS.")
assert(
!use_allocator_shim || is_linux || is_chromeos || is_android || is_win ||
is_apple,
"use_allocator_shim works only on Android, iOS, Linux, macOS, and Windows.")
if (is_win && use_allocator_shim) {
assert(!is_component_build,
"The allocator shim doesn't work for the component build on Windows.")
}

View File

@ -0,0 +1,46 @@
// Copyright 2016 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/allocator/allocator_check.h"
#include "base/allocator/buildflags.h"
#include "build/build_config.h"
#if defined(OS_WIN)
#include "base/allocator/winheap_stubs_win.h"
#endif
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#include <malloc.h>
#endif
#if defined(OS_APPLE)
#include "base/allocator/allocator_interception_mac.h"
#endif
namespace base {
namespace allocator {
bool IsAllocatorInitialized() {
#if defined(OS_WIN) && BUILDFLAG(USE_ALLOCATOR_SHIM)
// Set by allocator_shim_override_ucrt_symbols_win.h when the
// shimmed _set_new_mode() is called.
return g_is_win_shim_layer_initialized;
#elif (defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
BUILDFLAG(USE_TCMALLOC) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
// From third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h.
// TODO(primiano): replace with an include once base can depend on allocator.
#define TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC 0xbeef42
return (mallopt(TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC, 0) ==
TC_MALLOPT_IS_OVERRIDDEN_BY_TCMALLOC);
#elif defined(OS_APPLE) && !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
// From allocator_interception_mac.mm.
return base::allocator::g_replaced_default_zone;
#else
return true;
#endif
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,18 @@
// Copyright 2016 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_ALLOCATOR_ALLOCATOR_ALLOCATOR_CHECK_H_
#define BASE_ALLOCATOR_ALLOCATOR_ALLOCATOR_CHECK_H_
#include "base/base_export.h"
namespace base {
namespace allocator {
BASE_EXPORT bool IsAllocatorInitialized();
} // namespace allocator
} // namespace base
#endif // BASE_ALLOCATOR_ALLOCATOR_ALLOCATOR_CHECK_H_

View File

@ -0,0 +1,77 @@
// Copyright (c) 2012 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/allocator/allocator_extension.h"
#include "base/allocator/buildflags.h"
#include "base/check.h"
#if BUILDFLAG(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
#include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
#include "third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h"
#endif
namespace base {
namespace allocator {
void ReleaseFreeMemory() {
#if BUILDFLAG(USE_TCMALLOC)
::MallocExtension::instance()->ReleaseFreeMemory();
#endif
}
bool GetNumericProperty(const char* name, size_t* value) {
#if BUILDFLAG(USE_TCMALLOC)
return ::MallocExtension::instance()->GetNumericProperty(name, value);
#else
return false;
#endif
}
bool SetNumericProperty(const char* name, size_t value) {
#if BUILDFLAG(USE_TCMALLOC)
return ::MallocExtension::instance()->SetNumericProperty(name, value);
#else
return false;
#endif
}
void GetHeapSample(std::string* writer) {
#if BUILDFLAG(USE_TCMALLOC)
::MallocExtension::instance()->GetHeapSample(writer);
#endif
}
bool IsHeapProfilerRunning() {
#if BUILDFLAG(USE_TCMALLOC) && defined(ENABLE_PROFILING)
return ::IsHeapProfilerRunning();
#else
return false;
#endif
}
void SetHooks(AllocHookFunc alloc_hook, FreeHookFunc free_hook) {
// TODO(sque): Use allocator shim layer instead.
#if BUILDFLAG(USE_TCMALLOC)
// Make sure no hooks get overwritten.
auto prev_alloc_hook = MallocHook::SetNewHook(alloc_hook);
if (alloc_hook)
DCHECK(!prev_alloc_hook);
auto prev_free_hook = MallocHook::SetDeleteHook(free_hook);
if (free_hook)
DCHECK(!prev_free_hook);
#endif
}
int GetCallStack(void** stack, int max_stack_size) {
#if BUILDFLAG(USE_TCMALLOC)
return MallocHook::GetCallerStackTrace(stack, max_stack_size, 0);
#else
return 0;
#endif
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,67 @@
// Copyright (c) 2012 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_ALLOCATOR_ALLOCATOR_EXTENSION_H_
#define BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H_
#include <stddef.h> // for size_t
#include <string>
#include "base/base_export.h"
#include "build/build_config.h"
namespace base {
namespace allocator {
// Callback types for alloc and free.
using AllocHookFunc = void (*)(const void*, size_t);
using FreeHookFunc = void (*)(const void*);
// Request that the allocator release any free memory it knows about to the
// system.
BASE_EXPORT void ReleaseFreeMemory();
// Get the named property's |value|. Returns true if the property is known.
// Returns false if the property is not a valid property name for the current
// allocator implementation.
// |name| or |value| cannot be NULL
BASE_EXPORT bool GetNumericProperty(const char* name, size_t* value);
// Set the named property's |value|. Returns true if the property is known and
// writable. Returns false if the property is not a valid property name for the
// current allocator implementation, or is not writable. |name| cannot be NULL.
BASE_EXPORT bool SetNumericProperty(const char* name, size_t value);
// Outputs to |writer| a sample of live objects and the stack traces
// that allocated these objects. The format of the returned output
// is equivalent to the output of the heap profiler and can
// therefore be passed to "pprof".
// NOTE: by default, the allocator does not do any heap sampling, and this
// function will always return an empty sample. To get useful
// data from GetHeapSample, you must also set the numeric property
// "tcmalloc.sampling_period_bytes" to a value such as 524288.
BASE_EXPORT void GetHeapSample(std::string* writer);
BASE_EXPORT bool IsHeapProfilerRunning();
// Register callbacks for alloc and free. Can only store one callback at a time
// for each of alloc and free.
BASE_EXPORT void SetHooks(AllocHookFunc alloc_hook, FreeHookFunc free_hook);
// Attempts to unwind the call stack from the current location where this
// function is being called from. Must be called from a hook function registered
// by calling SetSingle{Alloc,Free}Hook, directly or indirectly.
//
// Arguments:
// stack: pointer to a pre-allocated array of void*'s.
// max_stack_size: indicates the size of the array in |stack|.
//
// Returns the number of call stack frames stored in |stack|, or 0 if no call
// stack information is available.
BASE_EXPORT int GetCallStack(void** stack, int max_stack_size);
} // namespace allocator
} // namespace base
#endif // BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H_

View File

@ -0,0 +1,61 @@
// Copyright 2017 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_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
#define BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_
#include <stddef.h>
#include "base/base_export.h"
#include "third_party/apple_apsl/malloc.h"
namespace base {
namespace allocator {
struct MallocZoneFunctions;
// This initializes AllocatorDispatch::default_dispatch by saving pointers to
// the functions in the current default malloc zone. This must be called before
// the default malloc zone is changed to have its intended effect.
void InitializeDefaultDispatchToMacAllocator();
// Saves the function pointers currently used by the default zone.
void StoreFunctionsForDefaultZone();
// Same as StoreFunctionsForDefaultZone, but for all malloc zones.
void StoreFunctionsForAllZones();
// For all malloc zones that have been stored, replace their functions with
// |functions|.
void ReplaceFunctionsForStoredZones(const MallocZoneFunctions* functions);
extern bool g_replaced_default_zone;
// Calls the original implementation of malloc/calloc prior to interception.
bool UncheckedMallocMac(size_t size, void** result);
bool UncheckedCallocMac(size_t num_items, size_t size, void** result);
// Intercepts calls to default and purgeable malloc zones. Intercepts Core
// Foundation and Objective-C allocations.
// Has no effect on the default malloc zone if the allocator shim already
// performs that interception.
BASE_EXPORT void InterceptAllocationsMac();
// Updates all malloc zones to use their original functions.
// Also calls ClearAllMallocZonesForTesting.
BASE_EXPORT void UninterceptMallocZonesForTesting();
// Periodically checks for, and shims new malloc zones. Stops checking after 1
// minute.
BASE_EXPORT void PeriodicallyShimNewMallocZones();
// Exposed for testing.
BASE_EXPORT void ShimNewMallocZones();
BASE_EXPORT void ReplaceZoneFunctions(ChromeMallocZone* zone,
const MallocZoneFunctions* functions);
} // namespace allocator
} // namespace base
#endif // BASE_ALLOCATOR_ALLOCATOR_INTERCEPTION_MAC_H_

View File

@ -0,0 +1,579 @@
// Copyright 2017 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.
// This file contains all the logic necessary to intercept allocations on
// macOS. "malloc zones" are an abstraction that allows the process to intercept
// all malloc-related functions. There is no good mechanism [short of
// interposition] to determine new malloc zones are added, so there's no clean
// mechanism to intercept all malloc zones. This file contains logic to
// intercept the default and purgeable zones, which always exist. A cursory
// review of Chrome seems to imply that non-default zones are almost never used.
//
// This file also contains logic to intercept Core Foundation and Objective-C
// allocations. The implementations forward to the default malloc zone, so the
// only reason to intercept these calls is to re-label OOM crashes with slightly
// more details.
#include "base/allocator/allocator_interception_mac.h"
#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <errno.h>
#include <mach/mach.h>
#import <objc/runtime.h>
#include <stddef.h>
#include <new>
#include "base/allocator/buildflags.h"
#include "base/allocator/malloc_zone_functions_mac.h"
#include "base/bind.h"
#include "base/bits.h"
#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/process/memory.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "third_party/apple_apsl/CFBase.h"
#if defined(OS_IOS)
#include "base/ios/ios_util.h"
#else
#include "base/mac/mac_util.h"
#endif
namespace base {
namespace allocator {
bool g_replaced_default_zone = false;
namespace {
bool g_oom_killer_enabled;
// Starting with Mac OS X 10.7, the zone allocators set up by the system are
// read-only, to prevent them from being overwritten in an attack. However,
// blindly unprotecting and reprotecting the zone allocators fails with
// GuardMalloc because GuardMalloc sets up its zone allocator using a block of
// memory in its bss. Explicit saving/restoring of the protection is required.
//
// This function takes a pointer to a malloc zone, de-protects it if necessary,
// and returns (in the out parameters) a region of memory (if any) to be
// re-protected when modifications are complete. This approach assumes that
// there is no contention for the protection of this memory.
void DeprotectMallocZone(ChromeMallocZone* default_zone,
vm_address_t* reprotection_start,
vm_size_t* reprotection_length,
vm_prot_t* reprotection_value) {
mach_port_t unused;
*reprotection_start = reinterpret_cast<vm_address_t>(default_zone);
struct vm_region_basic_info_64 info;
mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
kern_return_t result =
vm_region_64(mach_task_self(), reprotection_start, reprotection_length,
VM_REGION_BASIC_INFO_64,
reinterpret_cast<vm_region_info_t>(&info), &count, &unused);
MACH_CHECK(result == KERN_SUCCESS, result) << "vm_region_64";
// The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but
// balance it with a deallocate in case this ever changes. See
// the VM_REGION_BASIC_INFO_64 case in vm_map_region() in 10.15's
// https://opensource.apple.com/source/xnu/xnu-6153.11.26/osfmk/vm/vm_map.c .
mach_port_deallocate(mach_task_self(), unused);
// Does the region fully enclose the zone pointers? Possibly unwarranted
// simplification used: using the size of a full version 10 malloc zone rather
// than the actual smaller size if the passed-in zone is not version 10.
CHECK(*reprotection_start <= reinterpret_cast<vm_address_t>(default_zone));
vm_size_t zone_offset = reinterpret_cast<vm_address_t>(default_zone) -
reinterpret_cast<vm_address_t>(*reprotection_start);
CHECK(zone_offset + sizeof(ChromeMallocZone) <= *reprotection_length);
if (info.protection & VM_PROT_WRITE) {
// No change needed; the zone is already writable.
*reprotection_start = 0;
*reprotection_length = 0;
*reprotection_value = VM_PROT_NONE;
} else {
*reprotection_value = info.protection;
result =
vm_protect(mach_task_self(), *reprotection_start, *reprotection_length,
false, info.protection | VM_PROT_WRITE);
MACH_CHECK(result == KERN_SUCCESS, result) << "vm_protect";
}
}
#if !defined(ADDRESS_SANITIZER)
MallocZoneFunctions g_old_zone;
MallocZoneFunctions g_old_purgeable_zone;
void* oom_killer_malloc(struct _malloc_zone_t* zone, size_t size) {
void* result = g_old_zone.malloc(zone, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void* oom_killer_calloc(struct _malloc_zone_t* zone,
size_t num_items,
size_t size) {
void* result = g_old_zone.calloc(zone, num_items, size);
if (!result && num_items && size)
TerminateBecauseOutOfMemory(num_items * size);
return result;
}
void* oom_killer_valloc(struct _malloc_zone_t* zone, size_t size) {
void* result = g_old_zone.valloc(zone, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void oom_killer_free(struct _malloc_zone_t* zone, void* ptr) {
g_old_zone.free(zone, ptr);
}
void* oom_killer_realloc(struct _malloc_zone_t* zone, void* ptr, size_t size) {
void* result = g_old_zone.realloc(zone, ptr, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void* oom_killer_memalign(struct _malloc_zone_t* zone,
size_t alignment,
size_t size) {
void* result = g_old_zone.memalign(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why null might be returned. See posix_memalign() in 10.15's
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c .
if (!result && size && alignment >= sizeof(void*) &&
base::bits::IsPowerOfTwo(alignment)) {
TerminateBecauseOutOfMemory(size);
}
return result;
}
void* oom_killer_malloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
void* result = g_old_purgeable_zone.malloc(zone, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void* oom_killer_calloc_purgeable(struct _malloc_zone_t* zone,
size_t num_items,
size_t size) {
void* result = g_old_purgeable_zone.calloc(zone, num_items, size);
if (!result && num_items && size)
TerminateBecauseOutOfMemory(num_items * size);
return result;
}
void* oom_killer_valloc_purgeable(struct _malloc_zone_t* zone, size_t size) {
void* result = g_old_purgeable_zone.valloc(zone, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void oom_killer_free_purgeable(struct _malloc_zone_t* zone, void* ptr) {
g_old_purgeable_zone.free(zone, ptr);
}
void* oom_killer_realloc_purgeable(struct _malloc_zone_t* zone,
void* ptr,
size_t size) {
void* result = g_old_purgeable_zone.realloc(zone, ptr, size);
if (!result && size)
TerminateBecauseOutOfMemory(size);
return result;
}
void* oom_killer_memalign_purgeable(struct _malloc_zone_t* zone,
size_t alignment,
size_t size) {
void* result = g_old_purgeable_zone.memalign(zone, alignment, size);
// Only die if posix_memalign would have returned ENOMEM, since there are
// other reasons why null might be returned. See posix_memalign() in 10.15's
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c .
if (!result && size && alignment >= sizeof(void*) &&
base::bits::IsPowerOfTwo(alignment)) {
TerminateBecauseOutOfMemory(size);
}
return result;
}
#endif // !defined(ADDRESS_SANITIZER)
#if !defined(ADDRESS_SANITIZER)
// === Core Foundation CFAllocators ===
bool CanGetContextForCFAllocator() {
#if defined(OS_IOS)
return !base::ios::IsRunningOnOrLater(14, 0, 0);
#else
return !base::mac::IsOSLaterThan11_DontCallThis();
#endif
}
CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
ChromeCFAllocatorLions* our_allocator = const_cast<ChromeCFAllocatorLions*>(
reinterpret_cast<const ChromeCFAllocatorLions*>(allocator));
return &our_allocator->_context;
}
CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
void* oom_killer_cfallocator_system_default(CFIndex alloc_size,
CFOptionFlags hint,
void* info) {
void* result = g_old_cfallocator_system_default(alloc_size, hint, info);
if (!result)
TerminateBecauseOutOfMemory(alloc_size);
return result;
}
void* oom_killer_cfallocator_malloc(CFIndex alloc_size,
CFOptionFlags hint,
void* info) {
void* result = g_old_cfallocator_malloc(alloc_size, hint, info);
if (!result)
TerminateBecauseOutOfMemory(alloc_size);
return result;
}
void* oom_killer_cfallocator_malloc_zone(CFIndex alloc_size,
CFOptionFlags hint,
void* info) {
void* result = g_old_cfallocator_malloc_zone(alloc_size, hint, info);
if (!result)
TerminateBecauseOutOfMemory(alloc_size);
return result;
}
#endif // !defined(ADDRESS_SANITIZER)
// === Cocoa NSObject allocation ===
typedef id (*allocWithZone_t)(id, SEL, NSZone*);
allocWithZone_t g_old_allocWithZone;
id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) {
id result = g_old_allocWithZone(self, _cmd, zone);
if (!result)
TerminateBecauseOutOfMemory(0);
return result;
}
void UninterceptMallocZoneForTesting(struct _malloc_zone_t* zone) {
ChromeMallocZone* chrome_zone = reinterpret_cast<ChromeMallocZone*>(zone);
if (!IsMallocZoneAlreadyStored(chrome_zone))
return;
MallocZoneFunctions& functions = GetFunctionsForZone(zone);
ReplaceZoneFunctions(chrome_zone, &functions);
}
} // namespace
bool UncheckedMallocMac(size_t size, void** result) {
#if defined(ADDRESS_SANITIZER)
*result = malloc(size);
#else
if (g_old_zone.malloc) {
*result = g_old_zone.malloc(malloc_default_zone(), size);
} else {
*result = malloc(size);
}
#endif // defined(ADDRESS_SANITIZER)
return *result != NULL;
}
bool UncheckedCallocMac(size_t num_items, size_t size, void** result) {
#if defined(ADDRESS_SANITIZER)
*result = calloc(num_items, size);
#else
if (g_old_zone.calloc) {
*result = g_old_zone.calloc(malloc_default_zone(), num_items, size);
} else {
*result = calloc(num_items, size);
}
#endif // defined(ADDRESS_SANITIZER)
return *result != NULL;
}
void InitializeDefaultDispatchToMacAllocator() {
StoreFunctionsForAllZones();
}
void StoreFunctionsForDefaultZone() {
ChromeMallocZone* default_zone = reinterpret_cast<ChromeMallocZone*>(
malloc_default_zone());
StoreMallocZone(default_zone);
}
void StoreFunctionsForAllZones() {
// This ensures that the default zone is always at the front of the array,
// which is important for performance.
StoreFunctionsForDefaultZone();
vm_address_t* zones;
unsigned int count;
kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
if (kr != KERN_SUCCESS)
return;
for (unsigned int i = 0; i < count; ++i) {
ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]);
StoreMallocZone(zone);
}
}
void ReplaceFunctionsForStoredZones(const MallocZoneFunctions* functions) {
// The default zone does not get returned in malloc_get_all_zones().
ChromeMallocZone* default_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
if (DoesMallocZoneNeedReplacing(default_zone, functions)) {
ReplaceZoneFunctions(default_zone, functions);
}
vm_address_t* zones;
unsigned int count;
kern_return_t kr =
malloc_get_all_zones(mach_task_self(), nullptr, &zones, &count);
if (kr != KERN_SUCCESS)
return;
for (unsigned int i = 0; i < count; ++i) {
ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]);
if (DoesMallocZoneNeedReplacing(zone, functions)) {
ReplaceZoneFunctions(zone, functions);
}
}
g_replaced_default_zone = true;
}
void InterceptAllocationsMac() {
if (g_oom_killer_enabled)
return;
g_oom_killer_enabled = true;
// === C malloc/calloc/valloc/realloc/posix_memalign ===
// This approach is not perfect, as requests for amounts of memory larger than
// MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will still
// fail with a NULL rather than dying (see malloc_zone_malloc() in
// https://opensource.apple.com/source/libmalloc/libmalloc-283/src/malloc.c for
// details). Unfortunately, it's the best we can do. Also note that this does
// not affect allocations from non-default zones.
#if !defined(ADDRESS_SANITIZER)
// Don't do anything special on OOM for the malloc zones replaced by
// AddressSanitizer, as modifying or protecting them may not work correctly.
ChromeMallocZone* default_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
if (!IsMallocZoneAlreadyStored(default_zone)) {
StoreZoneFunctions(default_zone, &g_old_zone);
MallocZoneFunctions new_functions = {};
new_functions.malloc = oom_killer_malloc;
new_functions.calloc = oom_killer_calloc;
new_functions.valloc = oom_killer_valloc;
new_functions.free = oom_killer_free;
new_functions.realloc = oom_killer_realloc;
new_functions.memalign = oom_killer_memalign;
ReplaceZoneFunctions(default_zone, &new_functions);
g_replaced_default_zone = true;
}
ChromeMallocZone* purgeable_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
if (purgeable_zone && !IsMallocZoneAlreadyStored(purgeable_zone)) {
StoreZoneFunctions(purgeable_zone, &g_old_purgeable_zone);
MallocZoneFunctions new_functions = {};
new_functions.malloc = oom_killer_malloc_purgeable;
new_functions.calloc = oom_killer_calloc_purgeable;
new_functions.valloc = oom_killer_valloc_purgeable;
new_functions.free = oom_killer_free_purgeable;
new_functions.realloc = oom_killer_realloc_purgeable;
new_functions.memalign = oom_killer_memalign_purgeable;
ReplaceZoneFunctions(purgeable_zone, &new_functions);
}
#endif
// === C malloc_zone_batch_malloc ===
// batch_malloc is omitted because the default malloc zone's implementation
// only supports batch_malloc for "tiny" allocations from the free list. It
// will fail for allocations larger than "tiny", and will only allocate as
// many blocks as it's able to from the free list. These factors mean that it
// can return less than the requested memory even in a non-out-of-memory
// situation. There's no good way to detect whether a batch_malloc failure is
// due to these other factors, or due to genuine memory or address space
// exhaustion. The fact that it only allocates space from the "tiny" free list
// means that it's likely that a failure will not be due to memory exhaustion.
// Similarly, these constraints on batch_malloc mean that callers must always
// be expecting to receive less memory than was requested, even in situations
// where memory pressure is not a concern. Finally, the only public interface
// to batch_malloc is malloc_zone_batch_malloc, which is specific to the
// system's malloc implementation. It's unlikely that anyone's even heard of
// it.
#ifndef ADDRESS_SANITIZER
// === Core Foundation CFAllocators ===
// This will not catch allocation done by custom allocators, but will catch
// all allocation done by system-provided ones.
CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
!g_old_cfallocator_malloc_zone)
<< "Old allocators unexpectedly non-null";
bool cf_allocator_internals_known = CanGetContextForCFAllocator();
if (cf_allocator_internals_known) {
CFAllocatorContext* context =
ContextForCFAllocator(kCFAllocatorSystemDefault);
CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
g_old_cfallocator_system_default = context->allocate;
CHECK(g_old_cfallocator_system_default)
<< "Failed to get kCFAllocatorSystemDefault allocation function.";
context->allocate = oom_killer_cfallocator_system_default;
context = ContextForCFAllocator(kCFAllocatorMalloc);
CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
g_old_cfallocator_malloc = context->allocate;
CHECK(g_old_cfallocator_malloc)
<< "Failed to get kCFAllocatorMalloc allocation function.";
context->allocate = oom_killer_cfallocator_malloc;
context = ContextForCFAllocator(kCFAllocatorMallocZone);
CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
g_old_cfallocator_malloc_zone = context->allocate;
CHECK(g_old_cfallocator_malloc_zone)
<< "Failed to get kCFAllocatorMallocZone allocation function.";
context->allocate = oom_killer_cfallocator_malloc_zone;
} else {
DLOG(WARNING) << "Internals of CFAllocator not known; out-of-memory "
"failures via CFAllocator will not result in termination. "
"http://crbug.com/45650";
}
#endif
// === Cocoa NSObject allocation ===
// Note that both +[NSObject new] and +[NSObject alloc] call through to
// +[NSObject allocWithZone:].
CHECK(!g_old_allocWithZone) << "Old allocator unexpectedly non-null";
Class nsobject_class = [NSObject class];
Method orig_method =
class_getClassMethod(nsobject_class, @selector(allocWithZone:));
g_old_allocWithZone =
reinterpret_cast<allocWithZone_t>(method_getImplementation(orig_method));
CHECK(g_old_allocWithZone)
<< "Failed to get allocWithZone allocation function.";
method_setImplementation(orig_method,
reinterpret_cast<IMP>(oom_killer_allocWithZone));
}
void UninterceptMallocZonesForTesting() {
UninterceptMallocZoneForTesting(malloc_default_zone());
vm_address_t* zones;
unsigned int count;
kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
CHECK(kr == KERN_SUCCESS);
for (unsigned int i = 0; i < count; ++i) {
UninterceptMallocZoneForTesting(
reinterpret_cast<struct _malloc_zone_t*>(zones[i]));
}
ClearAllMallocZonesForTesting();
}
namespace {
void ShimNewMallocZonesAndReschedule(base::Time end_time,
base::TimeDelta delay) {
ShimNewMallocZones();
if (base::Time::Now() > end_time)
return;
base::TimeDelta next_delay = delay * 2;
SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&ShimNewMallocZonesAndReschedule, end_time, next_delay),
delay);
}
} // namespace
void PeriodicallyShimNewMallocZones() {
base::Time end_time = base::Time::Now() + base::TimeDelta::FromMinutes(1);
base::TimeDelta initial_delay = base::TimeDelta::FromSeconds(1);
ShimNewMallocZonesAndReschedule(end_time, initial_delay);
}
void ShimNewMallocZones() {
StoreFunctionsForAllZones();
// Use the functions for the default zone as a template to replace those
// new zones.
ChromeMallocZone* default_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
DCHECK(IsMallocZoneAlreadyStored(default_zone));
MallocZoneFunctions new_functions;
StoreZoneFunctions(default_zone, &new_functions);
ReplaceFunctionsForStoredZones(&new_functions);
}
void ReplaceZoneFunctions(ChromeMallocZone* zone,
const MallocZoneFunctions* functions) {
// Remove protection.
vm_address_t reprotection_start = 0;
vm_size_t reprotection_length = 0;
vm_prot_t reprotection_value = VM_PROT_NONE;
DeprotectMallocZone(zone, &reprotection_start, &reprotection_length,
&reprotection_value);
CHECK(functions->malloc && functions->calloc && functions->valloc &&
functions->free && functions->realloc);
zone->malloc = functions->malloc;
zone->calloc = functions->calloc;
zone->valloc = functions->valloc;
zone->free = functions->free;
zone->realloc = functions->realloc;
if (functions->batch_malloc)
zone->batch_malloc = functions->batch_malloc;
if (functions->batch_free)
zone->batch_free = functions->batch_free;
if (functions->size)
zone->size = functions->size;
if (zone->version >= 5 && functions->memalign) {
zone->memalign = functions->memalign;
}
if (zone->version >= 6 && functions->free_definite_size) {
zone->free_definite_size = functions->free_definite_size;
}
// Restore protection if it was active.
if (reprotection_start) {
kern_return_t result =
vm_protect(mach_task_self(), reprotection_start, reprotection_length,
false, reprotection_value);
MACH_CHECK(result == KERN_SUCCESS, result) << "vm_protect";
}
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,64 @@
// Copyright 2017 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 <mach/mach.h>
#include "base/allocator/allocator_interception_mac.h"
#include "base/allocator/allocator_shim.h"
#include "base/allocator/malloc_zone_functions_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace allocator {
namespace {
void ResetMallocZone(ChromeMallocZone* zone) {
MallocZoneFunctions& functions = GetFunctionsForZone(zone);
ReplaceZoneFunctions(zone, &functions);
}
void ResetAllMallocZones() {
ChromeMallocZone* default_malloc_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
ResetMallocZone(default_malloc_zone);
vm_address_t* zones;
unsigned int count;
kern_return_t kr = malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
if (kr != KERN_SUCCESS)
return;
for (unsigned int i = 0; i < count; ++i) {
ChromeMallocZone* zone = reinterpret_cast<ChromeMallocZone*>(zones[i]);
ResetMallocZone(zone);
}
}
} // namespace
class AllocatorInterceptionTest : public testing::Test {
protected:
void TearDown() override {
ResetAllMallocZones();
ClearAllMallocZonesForTesting();
}
};
#if !defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
TEST_F(AllocatorInterceptionTest, ShimNewMallocZones) {
InitializeAllocatorShim();
ChromeMallocZone* default_malloc_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
malloc_zone_t new_zone;
memset(&new_zone, 1, sizeof(malloc_zone_t));
malloc_zone_register(&new_zone);
EXPECT_NE(new_zone.malloc, default_malloc_zone->malloc);
ShimNewMallocZones();
EXPECT_EQ(new_zone.malloc, default_malloc_zone->malloc);
malloc_zone_unregister(&new_zone);
}
#endif
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,389 @@
// Copyright 2016 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/allocator/allocator_shim.h"
#include <errno.h>
#include <atomic>
#include <new>
#include "base/allocator/buildflags.h"
#include "base/bits.h"
#include "base/check_op.h"
#include "base/macros.h"
#include "base/process/process_metrics.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#if !defined(OS_WIN)
#include <unistd.h>
#else
#include "base/allocator/winheap_stubs_win.h"
#endif
#if defined(OS_APPLE)
#include <malloc/malloc.h>
#include "base/allocator/allocator_interception_mac.h"
#endif
// No calls to malloc / new in this file. They would would cause re-entrancy of
// the shim, which is hard to deal with. Keep this code as simple as possible
// and don't use any external C++ object here, not even //base ones. Even if
// they are safe to use today, in future they might be refactored.
namespace {
std::atomic<const base::allocator::AllocatorDispatch*> g_chain_head{
&base::allocator::AllocatorDispatch::default_dispatch};
bool g_call_new_handler_on_malloc_failure = false;
ALWAYS_INLINE size_t GetCachedPageSize() {
static size_t pagesize = 0;
if (!pagesize)
pagesize = base::GetPageSize();
return pagesize;
}
// Calls the std::new handler thread-safely. Returns true if a new_handler was
// set and called, false if no new_handler was set.
bool CallNewHandler(size_t size) {
#if defined(OS_WIN)
return base::allocator::WinCallNewHandler(size);
#else
std::new_handler nh = std::get_new_handler();
if (!nh)
return false;
(*nh)();
// Assume the new_handler will abort if it fails. Exception are disabled and
// we don't support the case of a new_handler throwing std::bad_balloc.
return true;
#endif
}
ALWAYS_INLINE const base::allocator::AllocatorDispatch* GetChainHead() {
return g_chain_head.load(std::memory_order_relaxed);
}
} // namespace
namespace base {
namespace allocator {
void SetCallNewHandlerOnMallocFailure(bool value) {
g_call_new_handler_on_malloc_failure = value;
}
void* UncheckedAlloc(size_t size) {
const allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->alloc_unchecked_function(chain_head, size, nullptr);
}
void InsertAllocatorDispatch(AllocatorDispatch* dispatch) {
// Loop in case of (an unlikely) race on setting the list head.
size_t kMaxRetries = 7;
for (size_t i = 0; i < kMaxRetries; ++i) {
const AllocatorDispatch* chain_head = GetChainHead();
dispatch->next = chain_head;
// This function guarantees to be thread-safe w.r.t. concurrent
// insertions. It also has to guarantee that all the threads always
// see a consistent chain, hence the atomic_thread_fence() below.
// InsertAllocatorDispatch() is NOT a fastpath, as opposite to malloc(), so
// we don't really want this to be a release-store with a corresponding
// acquire-load during malloc().
std::atomic_thread_fence(std::memory_order_seq_cst);
// Set the chain head to the new dispatch atomically. If we lose the race,
// retry.
if (g_chain_head.compare_exchange_strong(chain_head, dispatch,
std::memory_order_relaxed,
std::memory_order_relaxed)) {
// Success.
return;
}
}
CHECK(false); // Too many retries, this shouldn't happen.
}
void RemoveAllocatorDispatchForTesting(AllocatorDispatch* dispatch) {
DCHECK_EQ(GetChainHead(), dispatch);
g_chain_head.store(dispatch->next, std::memory_order_relaxed);
}
} // namespace allocator
} // namespace base
// The Shim* functions below are the entry-points into the shim-layer and
// are supposed to be invoked by the allocator_shim_override_*
// headers to route the malloc / new symbols through the shim layer.
// They are defined as ALWAYS_INLINE in order to remove a level of indirection
// between the system-defined entry points and the shim implementations.
extern "C" {
// The general pattern for allocations is:
// - Try to allocate, if succeded return the pointer.
// - If the allocation failed:
// - Call the std::new_handler if it was a C++ allocation.
// - Call the std::new_handler if it was a malloc() (or calloc() or similar)
// AND SetCallNewHandlerOnMallocFailure(true).
// - If the std::new_handler is NOT set just return nullptr.
// - If the std::new_handler is set:
// - Assume it will abort() if it fails (very likely the new_handler will
// just suicide priting a message).
// - Assume it did succeed if it returns, in which case reattempt the alloc.
ALWAYS_INLINE void* ShimCppNew(size_t size) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
void* context = nullptr;
#if defined(OS_APPLE)
context = malloc_default_zone();
#endif
ptr = chain_head->alloc_function(chain_head, size, context);
} while (!ptr && CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void* ShimCppAlignedNew(size_t size, size_t alignment) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
void* context = nullptr;
#if defined(OS_APPLE)
context = malloc_default_zone();
#endif
ptr = chain_head->alloc_aligned_function(chain_head, alignment, size,
context);
} while (!ptr && CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void ShimCppDelete(void* address) {
void* context = nullptr;
#if defined(OS_APPLE)
context = malloc_default_zone();
#endif
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->free_function(chain_head, address, context);
}
ALWAYS_INLINE void* ShimMalloc(size_t size, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
ptr = chain_head->alloc_function(chain_head, size, context);
} while (!ptr && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void* ShimCalloc(size_t n, size_t size, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
ptr = chain_head->alloc_zero_initialized_function(chain_head, n, size,
context);
} while (!ptr && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void* ShimRealloc(void* address, size_t size, void* context) {
// realloc(size == 0) means free() and might return a nullptr. We should
// not call the std::new_handler in that case, though.
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
ptr = chain_head->realloc_function(chain_head, address, size, context);
} while (!ptr && size && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void* ShimMemalign(size_t alignment, size_t size, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr;
do {
ptr = chain_head->alloc_aligned_function(chain_head, alignment, size,
context);
} while (!ptr && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE int ShimPosixMemalign(void** res, size_t alignment, size_t size) {
// posix_memalign is supposed to check the arguments. See tc_posix_memalign()
// in tc_malloc.cc.
if (((alignment % sizeof(void*)) != 0) ||
!base::bits::IsPowerOfTwo(alignment)) {
return EINVAL;
}
void* ptr = ShimMemalign(alignment, size, nullptr);
*res = ptr;
return ptr ? 0 : ENOMEM;
}
ALWAYS_INLINE void* ShimValloc(size_t size, void* context) {
return ShimMemalign(GetCachedPageSize(), size, context);
}
ALWAYS_INLINE void* ShimPvalloc(size_t size) {
// pvalloc(0) should allocate one page, according to its man page.
if (size == 0) {
size = GetCachedPageSize();
} else {
size = (size + GetCachedPageSize() - 1) & ~(GetCachedPageSize() - 1);
}
// The third argument is nullptr because pvalloc is glibc only and does not
// exist on OSX/BSD systems.
return ShimMemalign(GetCachedPageSize(), size, nullptr);
}
ALWAYS_INLINE void ShimFree(void* address, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->free_function(chain_head, address, context);
}
ALWAYS_INLINE size_t ShimGetSizeEstimate(const void* address, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->get_size_estimate_function(
chain_head, const_cast<void*>(address), context);
}
ALWAYS_INLINE unsigned ShimBatchMalloc(size_t size,
void** results,
unsigned num_requested,
void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->batch_malloc_function(chain_head, size, results,
num_requested, context);
}
ALWAYS_INLINE void ShimBatchFree(void** to_be_freed,
unsigned num_to_be_freed,
void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->batch_free_function(chain_head, to_be_freed,
num_to_be_freed, context);
}
ALWAYS_INLINE void ShimFreeDefiniteSize(void* ptr, size_t size, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->free_definite_size_function(chain_head, ptr, size,
context);
}
ALWAYS_INLINE void* ShimAlignedMalloc(size_t size,
size_t alignment,
void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr = nullptr;
do {
ptr = chain_head->aligned_malloc_function(chain_head, size, alignment,
context);
} while (!ptr && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void* ShimAlignedRealloc(void* address,
size_t size,
size_t alignment,
void* context) {
// _aligned_realloc(size == 0) means _aligned_free() and might return a
// nullptr. We should not call the std::new_handler in that case, though.
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
void* ptr = nullptr;
do {
ptr = chain_head->aligned_realloc_function(chain_head, address, size,
alignment, context);
} while (!ptr && size && g_call_new_handler_on_malloc_failure &&
CallNewHandler(size));
return ptr;
}
ALWAYS_INLINE void ShimAlignedFree(void* address, void* context) {
const base::allocator::AllocatorDispatch* const chain_head = GetChainHead();
return chain_head->aligned_free_function(chain_head, address, context);
}
} // extern "C"
#if !defined(OS_WIN) && !defined(OS_APPLE)
// Cpp symbols (new / delete) should always be routed through the shim layer
// except on Windows and macOS where the malloc intercept is deep enough that it
// also catches the cpp calls.
#include "base/allocator/allocator_shim_override_cpp_symbols.h"
#endif
#if defined(OS_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"
#elif defined(OS_WIN)
// On Windows we use plain link-time overriding of the CRT symbols.
#include "base/allocator/allocator_shim_override_ucrt_symbols_win.h"
#elif defined(OS_APPLE)
#include "base/allocator/allocator_shim_override_mac_symbols.h"
#else
#include "base/allocator/allocator_shim_override_libc_symbols.h"
#endif
// In the case of tcmalloc we also want to plumb into the glibc hooks
// to avoid that allocations made in glibc itself (e.g., strdup()) get
// accidentally performed on the glibc heap.
//
// More details:
// Some glibc versions (until commit 6c444ad6e953dbdf9c7be065308a0a777)
// incorrectly call __libc_memalign() to allocate memory (see elf/dl-tls.c in
// glibc 2.23 for instance), and free() to free it. This causes issues for us,
// as we are then asked to free memory we didn't allocate.
//
// This only happened in glibc to allocate TLS storage metadata, and there are
// no other callers of __libc_memalign() there as of September 2020. To work
// around this issue, intercept this internal libc symbol to make sure that both
// the allocation and the free() are caught by the shim.
//
// This seems fragile, and is, but there is ample precedent for it, making it
// quite likely to keep working in the future. For instance, both tcmalloc (in
// libc_override_glibc.h, see in third_party/tcmalloc) and LLVM for LSAN use the
// same mechanism.
#if defined(LIBC_GLIBC) && \
(BUILDFLAG(USE_TCMALLOC) || BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC))
#include "base/allocator/allocator_shim_override_glibc_weak_symbols.h"
#endif
#if defined(OS_APPLE)
namespace base {
namespace allocator {
void InitializeAllocatorShim() {
// Prepares the default dispatch. After the intercepted malloc calls have
// traversed the shim this will route them to the default malloc zone.
InitializeDefaultDispatchToMacAllocator();
MallocZoneFunctions functions = MallocZoneFunctionsToReplaceDefault();
// This replaces the default malloc zone, causing calls to malloc & friends
// from the codebase to be routed to ShimMalloc() above.
base::allocator::ReplaceFunctionsForStoredZones(&functions);
}
} // namespace allocator
} // namespace base
#endif
// Cross-checks.
#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
#error The allocator shim should not be compiled when building for memory tools.
#endif
#if (defined(__GNUC__) && defined(__EXCEPTIONS)) || \
(defined(_MSC_VER) && defined(_CPPUNWIND))
#error This code cannot be used when exceptions are turned on.
#endif

View File

@ -0,0 +1,156 @@
// Copyright 2016 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_ALLOCATOR_ALLOCATOR_SHIM_H_
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_H_
#include <stddef.h>
#include "base/base_export.h"
#include "build/build_config.h"
namespace base {
namespace allocator {
// Allocator Shim API. Allows to:
// - Configure the behavior of the allocator (what to do on OOM failures).
// - Install new hooks (AllocatorDispatch) in the allocator chain.
// When this shim layer is enabled, the route of an allocation is as-follows:
//
// [allocator_shim_override_*.h] Intercept malloc() / operator new calls:
// The override_* headers define the symbols required to intercept calls to
// malloc() and operator new (if not overridden by specific C++ classes).
//
// [allocator_shim.cc] Routing allocation calls to the shim:
// The headers above route the calls to the internal ShimMalloc(), ShimFree(),
// ShimCppNew() etc. methods defined in allocator_shim.cc.
// These methods will: (1) forward the allocation call to the front of the
// AllocatorDispatch chain. (2) perform security hardenings (e.g., might
// call std::new_handler on OOM failure).
//
// [allocator_shim_default_dispatch_to_*.cc] The AllocatorDispatch chain:
// It is a singly linked list where each element is a struct with function
// pointers (|malloc_function|, |free_function|, etc). Normally the chain
// consists of a single AllocatorDispatch element, herein called
// the "default dispatch", which is statically defined at build time and
// ultimately routes the calls to the actual allocator defined by the build
// config (tcmalloc, glibc, ...).
//
// It is possible to dynamically insert further AllocatorDispatch stages
// to the front of the chain, for debugging / profiling purposes.
//
// All the functions must be thread safe. The shim does not enforce any
// serialization. This is to route to thread-aware allocators (e.g, tcmalloc)
// wihout introducing unnecessary perf hits.
struct AllocatorDispatch {
using AllocFn = void*(const AllocatorDispatch* self,
size_t size,
void* context);
using AllocUncheckedFn = void*(const AllocatorDispatch* self,
size_t size,
void* context);
using AllocZeroInitializedFn = void*(const AllocatorDispatch* self,
size_t n,
size_t size,
void* context);
using AllocAlignedFn = void*(const AllocatorDispatch* self,
size_t alignment,
size_t size,
void* context);
using ReallocFn = void*(const AllocatorDispatch* self,
void* address,
size_t size,
void* context);
using FreeFn = void(const AllocatorDispatch* self,
void* address,
void* context);
// Returns the best available estimate for the actual amount of memory
// consumed by the allocation |address|. If possible, this should include
// heap overhead or at least a decent estimate of the full cost of the
// allocation. If no good estimate is possible, returns zero.
using GetSizeEstimateFn = size_t(const AllocatorDispatch* self,
void* address,
void* context);
using BatchMallocFn = unsigned(const AllocatorDispatch* self,
size_t size,
void** results,
unsigned num_requested,
void* context);
using BatchFreeFn = void(const AllocatorDispatch* self,
void** to_be_freed,
unsigned num_to_be_freed,
void* context);
using FreeDefiniteSizeFn = void(const AllocatorDispatch* self,
void* ptr,
size_t size,
void* context);
using AlignedMallocFn = void*(const AllocatorDispatch* self,
size_t size,
size_t alignment,
void* context);
using AlignedReallocFn = void*(const AllocatorDispatch* self,
void* address,
size_t size,
size_t alignment,
void* context);
using AlignedFreeFn = void(const AllocatorDispatch* self,
void* address,
void* context);
AllocFn* const alloc_function;
AllocUncheckedFn* const alloc_unchecked_function;
AllocZeroInitializedFn* const alloc_zero_initialized_function;
AllocAlignedFn* const alloc_aligned_function;
ReallocFn* const realloc_function;
FreeFn* const free_function;
GetSizeEstimateFn* const get_size_estimate_function;
// batch_malloc, batch_free, and free_definite_size are specific to the OSX
// and iOS allocators.
BatchMallocFn* const batch_malloc_function;
BatchFreeFn* const batch_free_function;
FreeDefiniteSizeFn* const free_definite_size_function;
// _aligned_malloc, _aligned_realloc, and _aligned_free are specific to the
// Windows allocator.
AlignedMallocFn* const aligned_malloc_function;
AlignedReallocFn* const aligned_realloc_function;
AlignedFreeFn* const aligned_free_function;
const AllocatorDispatch* next;
// |default_dispatch| is statically defined by one (and only one) of the
// allocator_shim_default_dispatch_to_*.cc files, depending on the build
// configuration.
static const AllocatorDispatch default_dispatch;
};
// When true makes malloc behave like new, w.r.t calling the new_handler if
// the allocation fails (see set_new_mode() in Windows).
BASE_EXPORT void SetCallNewHandlerOnMallocFailure(bool value);
// Allocates |size| bytes or returns nullptr. It does NOT call the new_handler,
// regardless of SetCallNewHandlerOnMallocFailure().
BASE_EXPORT void* UncheckedAlloc(size_t size);
// Inserts |dispatch| in front of the allocator chain. This method is
// thread-safe w.r.t concurrent invocations of InsertAllocatorDispatch().
// The callers have responsibility for inserting a single dispatch no more
// than once.
BASE_EXPORT void InsertAllocatorDispatch(AllocatorDispatch* dispatch);
// Test-only. Rationale: (1) lack of use cases; (2) dealing safely with a
// removal of arbitrary elements from a singly linked list would require a lock
// in malloc(), which we really don't want.
BASE_EXPORT void RemoveAllocatorDispatchForTesting(AllocatorDispatch* dispatch);
#if defined(OS_APPLE)
// On macOS, the allocator shim needs to be turned on during runtime.
BASE_EXPORT void InitializeAllocatorShim();
#endif // defined(OS_APPLE)
} // namespace allocator
} // namespace base
#endif // BASE_ALLOCATOR_ALLOCATOR_SHIM_H_

View File

@ -0,0 +1,89 @@
// Copyright 2016 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/allocator/allocator_shim.h"
#include "base/compiler_specific.h"
#include <dlfcn.h>
#include <malloc.h>
// This translation unit defines a default dispatch for the allocator shim which
// routes allocations to libc functions.
// The code here is strongly inspired from tcmalloc's libc_override_glibc.h.
extern "C" {
void* __libc_malloc(size_t size);
void* __libc_calloc(size_t n, size_t size);
void* __libc_realloc(void* address, size_t size);
void* __libc_memalign(size_t alignment, size_t size);
void __libc_free(void* ptr);
} // extern "C"
namespace {
using base::allocator::AllocatorDispatch;
void* GlibcMalloc(const AllocatorDispatch*, size_t size, void* context) {
return __libc_malloc(size);
}
void* GlibcCalloc(const AllocatorDispatch*,
size_t n,
size_t size,
void* context) {
return __libc_calloc(n, size);
}
void* GlibcRealloc(const AllocatorDispatch*,
void* address,
size_t size,
void* context) {
return __libc_realloc(address, size);
}
void* GlibcMemalign(const AllocatorDispatch*,
size_t alignment,
size_t size,
void* context) {
return __libc_memalign(alignment, size);
}
void GlibcFree(const AllocatorDispatch*, void* address, void* context) {
__libc_free(address);
}
NO_SANITIZE("cfi-icall")
size_t GlibcGetSizeEstimate(const AllocatorDispatch*,
void* address,
void* context) {
// glibc does not expose an alias to resolve malloc_usable_size. Dynamically
// resolve it instead. This should be safe because glibc (and hence dlfcn)
// does not use malloc_size internally and so there should not be a risk of
// recursion.
using MallocUsableSizeFunction = decltype(malloc_usable_size)*;
static MallocUsableSizeFunction fn_ptr =
reinterpret_cast<MallocUsableSizeFunction>(
dlsym(RTLD_NEXT, "malloc_usable_size"));
return fn_ptr(address);
}
} // namespace
const AllocatorDispatch AllocatorDispatch::default_dispatch = {
&GlibcMalloc, /* alloc_function */
&GlibcMalloc, /* alloc_unchecked_function */
&GlibcCalloc, /* alloc_zero_initialized_function */
&GlibcMemalign, /* alloc_aligned_function */
&GlibcRealloc, /* realloc_function */
&GlibcFree, /* free_function */
&GlibcGetSizeEstimate, /* get_size_estimate_function */
nullptr, /* batch_malloc_function */
nullptr, /* batch_free_function */
nullptr, /* free_definite_size_function */
nullptr, /* aligned_malloc_function */
nullptr, /* aligned_realloc_function */
nullptr, /* aligned_free_function */
nullptr, /* next */
};

View File

@ -0,0 +1,77 @@
// Copyright 2016 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 <malloc.h>
#include "base/allocator/allocator_shim.h"
#include "build/build_config.h"
// This translation unit defines a default dispatch for the allocator shim which
// routes allocations to the original libc functions when using the link-time
// -Wl,-wrap,malloc approach (see README.md).
// The __real_X functions here are special symbols that the linker will relocate
// against the real "X" undefined symbol, so that __real_malloc becomes the
// equivalent of what an undefined malloc symbol reference would have been.
// This is the counterpart of allocator_shim_override_linker_wrapped_symbols.h,
// which routes the __wrap_X functions into the shim.
extern "C" {
void* __real_malloc(size_t);
void* __real_calloc(size_t, size_t);
void* __real_realloc(void*, size_t);
void* __real_memalign(size_t, size_t);
void* __real_free(void*);
} // extern "C"
namespace {
using base::allocator::AllocatorDispatch;
void* RealMalloc(const AllocatorDispatch*, size_t size, void* context) {
return __real_malloc(size);
}
void* RealCalloc(const AllocatorDispatch*,
size_t n,
size_t size,
void* context) {
return __real_calloc(n, size);
}
void* RealRealloc(const AllocatorDispatch*,
void* address,
size_t size,
void* context) {
return __real_realloc(address, size);
}
void* RealMemalign(const AllocatorDispatch*,
size_t alignment,
size_t size,
void* context) {
return __real_memalign(alignment, size);
}
void RealFree(const AllocatorDispatch*, void* address, void* context) {
__real_free(address);
}
} // namespace
const AllocatorDispatch AllocatorDispatch::default_dispatch = {
&RealMalloc, /* alloc_function */
&RealMalloc, /* alloc_unchecked_function */
&RealCalloc, /* alloc_zero_initialized_function */
&RealMemalign, /* alloc_aligned_function */
&RealRealloc, /* realloc_function */
&RealFree, /* free_function */
nullptr, /* get_size_estimate_function */
nullptr, /* batch_malloc_function */
nullptr, /* batch_free_function */
nullptr, /* free_definite_size_function */
nullptr, /* aligned_malloc_function */
nullptr, /* aligned_realloc_function */
nullptr, /* aligned_free_function */
nullptr, /* next */
};

View File

@ -0,0 +1,107 @@
// Copyright 2017 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 <utility>
#include "base/allocator/allocator_interception_mac.h"
#include "base/allocator/allocator_shim.h"
#include "base/allocator/malloc_zone_functions_mac.h"
namespace base {
namespace allocator {
namespace {
void* MallocImpl(const AllocatorDispatch*, size_t size, void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.malloc(reinterpret_cast<struct _malloc_zone_t*>(context),
size);
}
void* CallocImpl(const AllocatorDispatch*,
size_t n,
size_t size,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.calloc(reinterpret_cast<struct _malloc_zone_t*>(context), n,
size);
}
void* MemalignImpl(const AllocatorDispatch*,
size_t alignment,
size_t size,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.memalign(reinterpret_cast<struct _malloc_zone_t*>(context),
alignment, size);
}
void* ReallocImpl(const AllocatorDispatch*,
void* ptr,
size_t size,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.realloc(reinterpret_cast<struct _malloc_zone_t*>(context),
ptr, size);
}
void FreeImpl(const AllocatorDispatch*, void* ptr, void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
functions.free(reinterpret_cast<struct _malloc_zone_t*>(context), ptr);
}
size_t GetSizeEstimateImpl(const AllocatorDispatch*, void* ptr, void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.size(reinterpret_cast<struct _malloc_zone_t*>(context), ptr);
}
unsigned BatchMallocImpl(const AllocatorDispatch* self,
size_t size,
void** results,
unsigned num_requested,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
return functions.batch_malloc(
reinterpret_cast<struct _malloc_zone_t*>(context), size, results,
num_requested);
}
void BatchFreeImpl(const AllocatorDispatch* self,
void** to_be_freed,
unsigned num_to_be_freed,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
functions.batch_free(reinterpret_cast<struct _malloc_zone_t*>(context),
to_be_freed, num_to_be_freed);
}
void FreeDefiniteSizeImpl(const AllocatorDispatch* self,
void* ptr,
size_t size,
void* context) {
MallocZoneFunctions& functions = GetFunctionsForZone(context);
functions.free_definite_size(
reinterpret_cast<struct _malloc_zone_t*>(context), ptr, size);
}
} // namespace
const AllocatorDispatch AllocatorDispatch::default_dispatch = {
&MallocImpl, /* alloc_function */
&MallocImpl, /* alloc_unchecked_function */
&CallocImpl, /* alloc_zero_initialized_function */
&MemalignImpl, /* alloc_aligned_function */
&ReallocImpl, /* realloc_function */
&FreeImpl, /* free_function */
&GetSizeEstimateImpl, /* get_size_estimate_function */
&BatchMallocImpl, /* batch_malloc_function */
&BatchFreeImpl, /* batch_free_function */
&FreeDefiniteSizeImpl, /* free_definite_size_function */
nullptr, /* aligned_malloc_function */
nullptr, /* aligned_realloc_function */
nullptr, /* aligned_free_function */
nullptr, /* next */
};
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,228 @@
// Copyright 2020 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/allocator/allocator_shim.h"
#include "base/allocator/allocator_shim_internals.h"
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/allocator/partition_allocator/partition_alloc_constants.h"
#include "base/bits.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
namespace {
// We would usually make g_root a static local variable, as these are guaranteed
// to be thread-safe in C++11. However this does not work on Windows, as the
// initialization calls into the runtime, which is not prepared to handle it.
//
// To sidestep that, we implement our own equivalent to a local `static
// base::NoDestructor<base::ThreadSafePartitionRoot> root`.
//
// The ingredients are:
// - Placement new to avoid a static constructor, and a static destructor.
// - Double-checked locking to get the same guarantees as a static local
// variable.
// Lock for double-checked locking.
std::atomic<bool> g_initialization_lock;
std::atomic<base::ThreadSafePartitionRoot*> g_root_;
// Buffer for placement new.
uint8_t g_allocator_buffer[sizeof(base::ThreadSafePartitionRoot)];
base::ThreadSafePartitionRoot& Allocator() {
// Double-checked locking.
//
// The proper way to proceed is:
//
// auto* root = load_acquire(g_root);
// if (!root) {
// ScopedLock initialization_lock;
// root = load_relaxed(g_root);
// if (root)
// return root;
// new_root = Create new root.
// release_store(g_root, new_root);
// }
//
// We don't want to use a base::Lock here, so instead we use the
// compare-and-exchange on a lock variable, but this provides the same
// guarantees as a regular lock. The code could be made simpler as we have
// stricter requirements, but we stick to something close to a regular lock
// for ease of reading, as none of this is performance-critical anyway.
//
// If we boldly assume that initialization will always be single-threaded,
// then we could remove all these atomic operations, but this seems a bit too
// bold to try yet. Might be worth revisiting though, since this would remove
// a memory barrier at each load. We could probably guarantee single-threaded
// init by adding a static constructor which allocates (and hence triggers
// initialization before any other thread is created).
auto* root = g_root_.load(std::memory_order_acquire);
if (LIKELY(root))
return *root;
bool expected = false;
// Semantically equivalent to base::Lock::Acquire().
while (!g_initialization_lock.compare_exchange_strong(
expected, true, std::memory_order_acquire, std::memory_order_acquire)) {
}
root = g_root_.load(std::memory_order_relaxed);
// Someone beat us.
if (root) {
// Semantically equivalent to base::Lock::Release().
g_initialization_lock.store(false, std::memory_order_release);
return *root;
}
auto* new_root = new (g_allocator_buffer) base::ThreadSafePartitionRoot(
{base::PartitionOptions::Alignment::kRegular,
base::PartitionOptions::ThreadCache::kEnabled});
g_root_.store(new_root, std::memory_order_release);
// Semantically equivalent to base::Lock::Release().
g_initialization_lock.store(false, std::memory_order_release);
return *new_root;
}
using base::allocator::AllocatorDispatch;
void* PartitionMalloc(const AllocatorDispatch*, size_t size, void* context) {
return Allocator().AllocFlagsNoHooks(0, size);
}
void* PartitionMallocUnchecked(const AllocatorDispatch*,
size_t size,
void* context) {
return Allocator().AllocFlagsNoHooks(base::PartitionAllocReturnNull, size);
}
void* PartitionCalloc(const AllocatorDispatch*,
size_t n,
size_t size,
void* context) {
return Allocator().AllocFlagsNoHooks(base::PartitionAllocZeroFill, n * size);
}
base::ThreadSafePartitionRoot* AlignedAllocator() {
// Since the general-purpose allocator uses the thread cache, this one cannot.
static base::NoDestructor<base::ThreadSafePartitionRoot> aligned_allocator(
base::PartitionOptions{base::PartitionOptions::Alignment::kAlignedAlloc,
base::PartitionOptions::ThreadCache::kDisabled});
return aligned_allocator.get();
}
void* PartitionMemalign(const AllocatorDispatch*,
size_t alignment,
size_t size,
void* context) {
return AlignedAllocator()->AlignedAllocFlags(base::PartitionAllocNoHooks,
alignment, size);
}
void* PartitionAlignedAlloc(const AllocatorDispatch* dispatch,
size_t size,
size_t alignment,
void* context) {
return AlignedAllocator()->AlignedAllocFlags(base::PartitionAllocNoHooks,
alignment, size);
}
// aligned_realloc documentation is
// https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/aligned-realloc
// TODO(tasak): Expand the given memory block to the given size if possible.
// This realloc always free the original memory block and allocates a new memory
// block.
// TODO(tasak): Implement PartitionRoot<thread_safe>::AlignedReallocFlags and
// use it.
void* PartitionAlignedRealloc(const AllocatorDispatch* dispatch,
void* address,
size_t size,
size_t alignment,
void* context) {
void* new_ptr = nullptr;
if (size > 0) {
new_ptr = AlignedAllocator()->AlignedAllocFlags(base::PartitionAllocNoHooks,
alignment, size);
} else {
// size == 0 and address != null means just "free(address)".
if (address)
base::ThreadSafePartitionRoot::FreeNoHooks(address);
}
// The original memory block (specified by address) is unchanged if ENOMEM.
if (!new_ptr)
return nullptr;
// TODO(tasak): Need to compare the new alignment with the address' alignment.
// If the two alignments are not the same, need to return nullptr with EINVAL.
if (address) {
size_t usage = base::ThreadSafePartitionRoot::GetAllocatedSize(address);
size_t copy_size = usage > size ? size : usage;
memcpy(new_ptr, address, copy_size);
base::ThreadSafePartitionRoot::FreeNoHooks(address);
}
return new_ptr;
}
void* PartitionRealloc(const AllocatorDispatch*,
void* address,
size_t size,
void* context) {
return Allocator().ReallocFlags(base::PartitionAllocNoHooks, address, size,
"");
}
void PartitionFree(const AllocatorDispatch*, void* address, void* context) {
base::ThreadSafePartitionRoot::FreeNoHooks(address);
}
size_t PartitionGetSizeEstimate(const AllocatorDispatch*,
void* address,
void* context) {
// TODO(lizeb): Returns incorrect values for aligned allocations.
return base::ThreadSafePartitionRoot::GetAllocatedSize(address);
}
} // namespace
constexpr AllocatorDispatch AllocatorDispatch::default_dispatch = {
&PartitionMalloc, /* alloc_function */
&PartitionMallocUnchecked, /* alloc_unchecked_function */
&PartitionCalloc, /* alloc_zero_initialized_function */
&PartitionMemalign, /* alloc_aligned_function */
&PartitionRealloc, /* realloc_function */
&PartitionFree, /* free_function */
&PartitionGetSizeEstimate, /* get_size_estimate_function */
nullptr, /* batch_malloc_function */
nullptr, /* batch_free_function */
nullptr, /* free_definite_size_function */
&PartitionAlignedAlloc, /* aligned_malloc_function */
&PartitionAlignedRealloc, /* aligned_realloc_function */
&PartitionFree, /* aligned_free_function */
nullptr, /* next */
};
// Intercept diagnostics symbols as well, even though they are not part of the
// unified shim layer.
//
// TODO(lizeb): Implement the ones that doable.
extern "C" {
#if !defined(OS_APPLE)
SHIM_ALWAYS_EXPORT void malloc_stats(void) __THROW {}
SHIM_ALWAYS_EXPORT int mallopt(int cmd, int value) __THROW {
return 0;
}
#endif // !defined(OS_APPLE)
#ifdef HAVE_STRUCT_MALLINFO
SHIM_ALWAYS_EXPORT struct mallinfo mallinfo(void) __THROW {
return {};
}
#endif
} // extern "C"

View File

@ -0,0 +1,89 @@
// Copyright 2016 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/allocator/allocator_shim.h"
#include "base/allocator/allocator_shim_internals.h"
#include "third_party/tcmalloc/chromium/src/config.h"
#include "third_party/tcmalloc/chromium/src/gperftools/tcmalloc.h"
namespace {
using base::allocator::AllocatorDispatch;
void* TCMalloc(const AllocatorDispatch*, size_t size, void* context) {
return tc_malloc(size);
}
void* TCMallocUnchecked(const AllocatorDispatch*, size_t size, void* context) {
return tc_malloc_skip_new_handler(size);
}
void* TCCalloc(const AllocatorDispatch*, size_t n, size_t size, void* context) {
return tc_calloc(n, size);
}
void* TCMemalign(const AllocatorDispatch*,
size_t alignment,
size_t size,
void* context) {
return tc_memalign(alignment, size);
}
void* TCRealloc(const AllocatorDispatch*,
void* address,
size_t size,
void* context) {
return tc_realloc(address, size);
}
void TCFree(const AllocatorDispatch*, void* address, void* context) {
tc_free(address);
}
size_t TCGetSizeEstimate(const AllocatorDispatch*,
void* address,
void* context) {
return tc_malloc_size(address);
}
} // namespace
const AllocatorDispatch AllocatorDispatch::default_dispatch = {
&TCMalloc, /* alloc_function */
&TCMallocUnchecked, /* alloc_unchecked_function */
&TCCalloc, /* alloc_zero_initialized_function */
&TCMemalign, /* alloc_aligned_function */
&TCRealloc, /* realloc_function */
&TCFree, /* free_function */
&TCGetSizeEstimate, /* get_size_estimate_function */
nullptr, /* batch_malloc_function */
nullptr, /* batch_free_function */
nullptr, /* free_definite_size_function */
nullptr, /* aligned_malloc_function */
nullptr, /* aligned_realloc_function */
nullptr, /* aligned_free_function */
nullptr, /* next */
};
// In the case of tcmalloc we have also to route the diagnostic symbols,
// which are not part of the unified shim layer, to tcmalloc for consistency.
extern "C" {
SHIM_ALWAYS_EXPORT void malloc_stats(void) __THROW {
return tc_malloc_stats();
}
SHIM_ALWAYS_EXPORT int mallopt(int cmd, int value) __THROW {
return tc_mallopt(cmd, value);
}
#ifdef HAVE_STRUCT_MALLINFO
SHIM_ALWAYS_EXPORT struct mallinfo mallinfo(void) __THROW {
return tc_mallinfo();
}
#endif
} // extern "C"

View File

@ -0,0 +1,106 @@
// Copyright 2016 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/allocator/allocator_shim.h"
#include <ostream>
#include "base/allocator/winheap_stubs_win.h"
#include "base/check.h"
namespace {
using base::allocator::AllocatorDispatch;
void* DefaultWinHeapMallocImpl(const AllocatorDispatch*,
size_t size,
void* context) {
return base::allocator::WinHeapMalloc(size);
}
void* DefaultWinHeapCallocImpl(const AllocatorDispatch* self,
size_t n,
size_t elem_size,
void* context) {
// Overflow check.
const size_t size = n * elem_size;
if (elem_size != 0 && size / elem_size != n)
return nullptr;
void* result = DefaultWinHeapMallocImpl(self, size, context);
if (result) {
memset(result, 0, size);
}
return result;
}
void* DefaultWinHeapMemalignImpl(const AllocatorDispatch* self,
size_t alignment,
size_t size,
void* context) {
CHECK(false) << "The windows heap does not support memalign.";
return nullptr;
}
void* DefaultWinHeapReallocImpl(const AllocatorDispatch* self,
void* address,
size_t size,
void* context) {
return base::allocator::WinHeapRealloc(address, size);
}
void DefaultWinHeapFreeImpl(const AllocatorDispatch*,
void* address,
void* context) {
base::allocator::WinHeapFree(address);
}
size_t DefaultWinHeapGetSizeEstimateImpl(const AllocatorDispatch*,
void* address,
void* context) {
return base::allocator::WinHeapGetSizeEstimate(address);
}
void* DefaultWinHeapAlignedMallocImpl(const AllocatorDispatch*,
size_t size,
size_t alignment,
void* context) {
return base::allocator::WinHeapAlignedMalloc(size, alignment);
}
void* DefaultWinHeapAlignedReallocImpl(const AllocatorDispatch*,
void* ptr,
size_t size,
size_t alignment,
void* context) {
return base::allocator::WinHeapAlignedRealloc(ptr, size, alignment);
}
void DefaultWinHeapAlignedFreeImpl(const AllocatorDispatch*,
void* ptr,
void* context) {
base::allocator::WinHeapAlignedFree(ptr);
}
} // namespace
// Guarantee that default_dispatch is compile-time initialized to avoid using
// it before initialization (allocations before main in release builds with
// optimizations disabled).
constexpr AllocatorDispatch AllocatorDispatch::default_dispatch = {
&DefaultWinHeapMallocImpl,
&DefaultWinHeapMallocImpl, /* alloc_unchecked_function */
&DefaultWinHeapCallocImpl,
&DefaultWinHeapMemalignImpl,
&DefaultWinHeapReallocImpl,
&DefaultWinHeapFreeImpl,
&DefaultWinHeapGetSizeEstimateImpl,
nullptr, /* batch_malloc_function */
nullptr, /* batch_free_function */
nullptr, /* free_definite_size_function */
&DefaultWinHeapAlignedMallocImpl,
&DefaultWinHeapAlignedReallocImpl,
&DefaultWinHeapAlignedFreeImpl,
nullptr, /* next */
};

View File

@ -0,0 +1,51 @@
// Copyright 2016 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_ALLOCATOR_ALLOCATOR_SHIM_INTERNALS_H_
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_INTERNALS_H_
#include "build/build_config.h"
#if defined(__GNUC__)
#include <sys/cdefs.h> // for __THROW
#ifndef __THROW // Not a glibc system
#ifdef _NOEXCEPT // LLVM libc++ uses noexcept instead
#define __THROW _NOEXCEPT
#else
#define __THROW
#endif // !_NOEXCEPT
#endif
// Shim layer symbols need to be ALWAYS exported, regardless of component build.
//
// If an exported symbol is linked into a DSO, it may be preempted by a
// definition in the main executable. If this happens to an allocator symbol, it
// will mean that the DSO will use the main executable's allocator. This is
// normally relatively harmless -- regular allocations should all use the same
// allocator, but if the DSO tries to hook the allocator it will not see any
// allocations.
//
// However, if LLVM LTO is enabled, the compiler may inline the shim layer
// symbols into callers. The end result is that allocator calls in DSOs may use
// either the main executable's allocator or the DSO's allocator, depending on
// whether the call was inlined. This is arguably a bug in LLVM caused by its
// somewhat irregular handling of symbol interposition (see llvm.org/PR23501).
// To work around the bug we use noinline to prevent the symbols from being
// inlined.
//
// In the long run we probably want to avoid linking the allocator bits into
// DSOs altogether. This will save a little space and stop giving DSOs the false
// impression that they can hook the allocator.
#define SHIM_ALWAYS_EXPORT __attribute__((visibility("default"), noinline))
#elif defined(OS_WIN) // __GNUC__
#define __THROW
#define SHIM_ALWAYS_EXPORT __declspec(noinline)
#endif // __GNUC__
#endif // BASE_ALLOCATOR_ALLOCATOR_SHIM_INTERNALS_H_

View File

@ -0,0 +1,152 @@
// Copyright 2016 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.
#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_CPP_SYMBOLS_H_
#error This header is meant to be included only once by allocator_shim.cc
#endif
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_CPP_SYMBOLS_H_
// Preempt the default new/delete C++ symbols so they call the shim entry
// points. This file is strongly inspired by tcmalloc's
// libc_override_redefine.h.
#include <new>
#include "base/allocator/allocator_shim_internals.h"
#include "build/build_config.h"
// std::align_val_t isn't available until C++17, but we want to override aligned
// new/delete anyway to prevent a possible situation where a library gets loaded
// in that uses the aligned operators. We want to avoid a situation where
// separate heaps are used.
// TODO(thomasanderson): Remove this once building with C++17 or later.
#if defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606
#define ALIGN_VAL_T std::align_val_t
#define ALIGN_LINKAGE
#define ALIGN_NEW operator new
#define ALIGN_NEW_NOTHROW operator new
#define ALIGN_DEL operator delete
#define ALIGN_DEL_SIZED operator delete
#define ALIGN_DEL_NOTHROW operator delete
#define ALIGN_NEW_ARR operator new[]
#define ALIGN_NEW_ARR_NOTHROW operator new[]
#define ALIGN_DEL_ARR operator delete[]
#define ALIGN_DEL_ARR_SIZED operator delete[]
#define ALIGN_DEL_ARR_NOTHROW operator delete[]
#else
#define ALIGN_VAL_T size_t
#define ALIGN_LINKAGE extern "C"
#if defined(OS_APPLE) || defined(OS_WIN)
#error "Mangling is different on these platforms."
#else
#define ALIGN_NEW _ZnwmSt11align_val_t
#define ALIGN_NEW_NOTHROW _ZnwmSt11align_val_tRKSt9nothrow_t
#define ALIGN_DEL _ZdlPvSt11align_val_t
#define ALIGN_DEL_SIZED _ZdlPvmSt11align_val_t
#define ALIGN_DEL_NOTHROW _ZdlPvSt11align_val_tRKSt9nothrow_t
#define ALIGN_NEW_ARR _ZnamSt11align_val_t
#define ALIGN_NEW_ARR_NOTHROW _ZnamSt11align_val_tRKSt9nothrow_t
#define ALIGN_DEL_ARR _ZdaPvSt11align_val_t
#define ALIGN_DEL_ARR_SIZED _ZdaPvmSt11align_val_t
#define ALIGN_DEL_ARR_NOTHROW _ZdaPvSt11align_val_tRKSt9nothrow_t
#endif
#endif
SHIM_ALWAYS_EXPORT void* operator new(size_t size) {
return ShimCppNew(size);
}
SHIM_ALWAYS_EXPORT void operator delete(void* p) __THROW {
ShimCppDelete(p);
}
SHIM_ALWAYS_EXPORT void* operator new[](size_t size) {
return ShimCppNew(size);
}
SHIM_ALWAYS_EXPORT void operator delete[](void* p) __THROW {
ShimCppDelete(p);
}
SHIM_ALWAYS_EXPORT void* operator new(size_t size,
const std::nothrow_t&) __THROW {
return ShimCppNew(size);
}
SHIM_ALWAYS_EXPORT void* operator new[](size_t size,
const std::nothrow_t&) __THROW {
return ShimCppNew(size);
}
SHIM_ALWAYS_EXPORT void operator delete(void* p, const std::nothrow_t&) __THROW {
ShimCppDelete(p);
}
SHIM_ALWAYS_EXPORT void operator delete[](void* p,
const std::nothrow_t&) __THROW {
ShimCppDelete(p);
}
SHIM_ALWAYS_EXPORT void operator delete(void* p, size_t) __THROW {
ShimCppDelete(p);
}
SHIM_ALWAYS_EXPORT void operator delete[](void* p, size_t) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW(std::size_t size,
ALIGN_VAL_T alignment) {
return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_NOTHROW(
std::size_t size,
ALIGN_VAL_T alignment,
const std::nothrow_t&) __THROW {
return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL(void* p, ALIGN_VAL_T) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_SIZED(void* p,
std::size_t size,
ALIGN_VAL_T) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void
ALIGN_DEL_NOTHROW(void* p, ALIGN_VAL_T, const std::nothrow_t&) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_ARR(std::size_t size,
ALIGN_VAL_T alignment) {
return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void* ALIGN_NEW_ARR_NOTHROW(
std::size_t size,
ALIGN_VAL_T alignment,
const std::nothrow_t&) __THROW {
return ShimCppAlignedNew(size, static_cast<size_t>(alignment));
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_ARR(void* p,
ALIGN_VAL_T) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void ALIGN_DEL_ARR_SIZED(void* p,
std::size_t size,
ALIGN_VAL_T) __THROW {
ShimCppDelete(p);
}
ALIGN_LINKAGE SHIM_ALWAYS_EXPORT void
ALIGN_DEL_ARR_NOTHROW(void* p, ALIGN_VAL_T, const std::nothrow_t&) __THROW {
ShimCppDelete(p);
}

View File

@ -0,0 +1,119 @@
// Copyright 2016 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.
#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
#error This header is meant to be included only once by allocator_shim.cc
#endif
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
// Alias the internal Glibc symbols to the shim entry points.
// This file is strongly inspired by tcmalloc's libc_override_glibc.h.
// Effectively this file does two things:
// 1) Re-define the __malloc_hook & co symbols. Those symbols are defined as
// weak in glibc and are meant to be defined strongly by client processes
// to hook calls initiated from within glibc.
// 2) Re-define Glibc-specific symbols (__libc_malloc). The historical reason
// is that in the past (in RedHat 9) we had instances of libraries that were
// allocating via malloc() and freeing using __libc_free().
// See tcmalloc's libc_override_glibc.h for more context.
#include <features.h> // for __GLIBC__
#include <malloc.h>
#include <unistd.h>
#include <new>
#include "base/allocator/allocator_shim_internals.h"
// __MALLOC_HOOK_VOLATILE not defined in all Glibc headers.
#if !defined(__MALLOC_HOOK_VOLATILE)
#define MALLOC_HOOK_MAYBE_VOLATILE /**/
#else
#define MALLOC_HOOK_MAYBE_VOLATILE __MALLOC_HOOK_VOLATILE
#endif
extern "C" {
// 1) Re-define malloc_hook weak symbols.
namespace {
void* GlibcMallocHook(size_t size, const void* caller) {
return ShimMalloc(size, nullptr);
}
void* GlibcReallocHook(void* ptr, size_t size, const void* caller) {
return ShimRealloc(ptr, size, nullptr);
}
void GlibcFreeHook(void* ptr, const void* caller) {
return ShimFree(ptr, nullptr);
}
void* GlibcMemalignHook(size_t align, size_t size, const void* caller) {
return ShimMemalign(align, size, nullptr);
}
} // namespace
__attribute__((visibility("default"))) void* (
*MALLOC_HOOK_MAYBE_VOLATILE __malloc_hook)(size_t,
const void*) = &GlibcMallocHook;
__attribute__((visibility("default"))) void* (
*MALLOC_HOOK_MAYBE_VOLATILE __realloc_hook)(void*, size_t, const void*) =
&GlibcReallocHook;
__attribute__((visibility("default"))) void (
*MALLOC_HOOK_MAYBE_VOLATILE __free_hook)(void*,
const void*) = &GlibcFreeHook;
__attribute__((visibility("default"))) void* (
*MALLOC_HOOK_MAYBE_VOLATILE __memalign_hook)(size_t, size_t, const void*) =
&GlibcMemalignHook;
// 2) Redefine libc symbols themselves.
SHIM_ALWAYS_EXPORT void* __libc_malloc(size_t size) {
return ShimMalloc(size, nullptr);
}
SHIM_ALWAYS_EXPORT void __libc_free(void* ptr) {
ShimFree(ptr, nullptr);
}
SHIM_ALWAYS_EXPORT void* __libc_realloc(void* ptr, size_t size) {
return ShimRealloc(ptr, size, nullptr);
}
SHIM_ALWAYS_EXPORT void* __libc_calloc(size_t n, size_t size) {
return ShimCalloc(n, size, nullptr);
}
SHIM_ALWAYS_EXPORT void __libc_cfree(void* ptr) {
return ShimFree(ptr, nullptr);
}
SHIM_ALWAYS_EXPORT void* __libc_memalign(size_t align, size_t s) {
return ShimMemalign(align, s, nullptr);
}
SHIM_ALWAYS_EXPORT void* __libc_valloc(size_t size) {
return ShimValloc(size, nullptr);
}
SHIM_ALWAYS_EXPORT void* __libc_pvalloc(size_t size) {
return ShimPvalloc(size);
}
SHIM_ALWAYS_EXPORT int __posix_memalign(void** r, size_t a, size_t s) {
return ShimPosixMemalign(r, a, s);
}
} // extern "C"
// Safety check.
#if !defined(__GLIBC__)
#error The target platform does not seem to use Glibc. Disable the allocator \
shim by setting use_allocator_shim=false in GN args.
#endif

View File

@ -0,0 +1,73 @@
// Copyright 2016 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.
// Its purpose is to preempt the Libc symbols for malloc/new so they call the
// shim layer entry points.
#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_LIBC_SYMBOLS_H_
#error This header is meant to be included only once by allocator_shim.cc
#endif
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_LIBC_SYMBOLS_H_
#include <malloc.h>
#include "base/allocator/allocator_shim_internals.h"
extern "C" {
SHIM_ALWAYS_EXPORT void* malloc(size_t size) __THROW {
return ShimMalloc(size, nullptr);
}
SHIM_ALWAYS_EXPORT void free(void* ptr) __THROW {
ShimFree(ptr, nullptr);
}
SHIM_ALWAYS_EXPORT void* realloc(void* ptr, size_t size) __THROW {
return ShimRealloc(ptr, size, nullptr);
}
SHIM_ALWAYS_EXPORT void* calloc(size_t n, size_t size) __THROW {
return ShimCalloc(n, size, nullptr);
}
SHIM_ALWAYS_EXPORT void cfree(void* ptr) __THROW {
ShimFree(ptr, nullptr);
}
SHIM_ALWAYS_EXPORT void* memalign(size_t align, size_t s) __THROW {
return ShimMemalign(align, s, nullptr);
}
SHIM_ALWAYS_EXPORT void* aligned_alloc(size_t align, size_t s) __THROW {
return ShimMemalign(align, s, nullptr);
}
SHIM_ALWAYS_EXPORT void* valloc(size_t size) __THROW {
return ShimValloc(size, nullptr);
}
SHIM_ALWAYS_EXPORT void* pvalloc(size_t size) __THROW {
return ShimPvalloc(size);
}
SHIM_ALWAYS_EXPORT int posix_memalign(void** r, size_t a, size_t s) __THROW {
return ShimPosixMemalign(r, a, s);
}
SHIM_ALWAYS_EXPORT size_t malloc_size(void* address) __THROW {
return ShimGetSizeEstimate(address, nullptr);
}
SHIM_ALWAYS_EXPORT size_t malloc_usable_size(void* address) __THROW {
return ShimGetSizeEstimate(address, nullptr);
}
// The default dispatch translation unit has to define also the following
// symbols (unless they are ultimately routed to the system symbols):
// void malloc_stats(void);
// int mallopt(int, int);
// struct mallinfo mallinfo(void);
} // extern "C"

View File

@ -0,0 +1,77 @@
// Copyright 2016 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.
#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
#error This header is meant to be included only once by allocator_shim.cc
#endif
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
// This header overrides the __wrap_X symbols when using the link-time
// -Wl,-wrap,malloc shim-layer approach (see README.md).
// All references to malloc, free, etc. within the linker unit that gets the
// -wrap linker flags (e.g., libchrome.so) will be rewritten to the
// linker as references to __wrap_malloc, __wrap_free, which are defined here.
#include <algorithm>
#include <cstring>
#include "base/allocator/allocator_shim_internals.h"
extern "C" {
SHIM_ALWAYS_EXPORT void* __wrap_calloc(size_t n, size_t size) {
return ShimCalloc(n, size, nullptr);
}
SHIM_ALWAYS_EXPORT void __wrap_free(void* ptr) {
ShimFree(ptr, nullptr);
}
SHIM_ALWAYS_EXPORT void* __wrap_malloc(size_t size) {
return ShimMalloc(size, nullptr);
}
SHIM_ALWAYS_EXPORT void* __wrap_memalign(size_t align, size_t size) {
return ShimMemalign(align, size, nullptr);
}
SHIM_ALWAYS_EXPORT int __wrap_posix_memalign(void** res,
size_t align,
size_t size) {
return ShimPosixMemalign(res, align, size);
}
SHIM_ALWAYS_EXPORT void* __wrap_pvalloc(size_t size) {
return ShimPvalloc(size);
}
SHIM_ALWAYS_EXPORT void* __wrap_realloc(void* address, size_t size) {
return ShimRealloc(address, size, nullptr);
}
SHIM_ALWAYS_EXPORT void* __wrap_valloc(size_t size) {
return ShimValloc(size, nullptr);
}
// Override <string.h> functions
SHIM_ALWAYS_EXPORT char* __wrap_strdup(const char* str) {
std::size_t length = std::strlen(str) + 1;
void* buffer = ShimMalloc(length, nullptr);
if (!buffer)
return nullptr;
return reinterpret_cast<char*>(std::memcpy(buffer, str, length));
}
SHIM_ALWAYS_EXPORT char* __wrap_strndup(const char* str, size_t n) {
std::size_t length = std::min(std::strlen(str), n);
char* buffer = reinterpret_cast<char*>(ShimMalloc(length + 1, nullptr));
if (!buffer)
return nullptr;
std::memcpy(buffer, str, length);
buffer[length] = '\0';
return buffer;
}
} // extern "C"

View File

@ -0,0 +1,60 @@
// Copyright 2017 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.
#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_MAC_SYMBOLS_H_
#error This header is meant to be included only once by allocator_shim.cc
#endif
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_MAC_SYMBOLS_H_
#include "base/allocator/malloc_zone_functions_mac.h"
#include "third_party/apple_apsl/malloc.h"
namespace base {
namespace allocator {
MallocZoneFunctions MallocZoneFunctionsToReplaceDefault() {
MallocZoneFunctions new_functions;
memset(&new_functions, 0, sizeof(MallocZoneFunctions));
new_functions.size = [](malloc_zone_t* zone, const void* ptr) -> size_t {
return ShimGetSizeEstimate(ptr, zone);
};
new_functions.malloc = [](malloc_zone_t* zone, size_t size) -> void* {
return ShimMalloc(size, zone);
};
new_functions.calloc = [](malloc_zone_t* zone, size_t n,
size_t size) -> void* {
return ShimCalloc(n, size, zone);
};
new_functions.valloc = [](malloc_zone_t* zone, size_t size) -> void* {
return ShimValloc(size, zone);
};
new_functions.free = [](malloc_zone_t* zone, void* ptr) {
ShimFree(ptr, zone);
};
new_functions.realloc = [](malloc_zone_t* zone, void* ptr,
size_t size) -> void* {
return ShimRealloc(ptr, size, zone);
};
new_functions.batch_malloc = [](struct _malloc_zone_t* zone, size_t size,
void** results,
unsigned num_requested) -> unsigned {
return ShimBatchMalloc(size, results, num_requested, zone);
};
new_functions.batch_free = [](struct _malloc_zone_t* zone, void** to_be_freed,
unsigned num_to_be_freed) -> void {
ShimBatchFree(to_be_freed, num_to_be_freed, zone);
};
new_functions.memalign = [](malloc_zone_t* zone, size_t alignment,
size_t size) -> void* {
return ShimMemalign(alignment, size, zone);
};
new_functions.free_definite_size = [](malloc_zone_t* zone, void* ptr,
size_t size) {
ShimFreeDefiniteSize(ptr, size, zone);
};
return new_functions;
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,162 @@
// Copyright 2016 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.
// This header defines symbols to override the same functions in the Visual C++
// CRT implementation.
#ifndef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_UCRT_SYMBOLS_WIN_H_
#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_UCRT_SYMBOLS_WIN_H_
#include <malloc.h>
#include <windows.h>
extern "C" {
void* (*malloc_unchecked)(size_t) = &base::allocator::UncheckedAlloc;
namespace {
int win_new_mode = 0;
} // namespace
// This function behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Returns the previous mode.
//
// Replaces _set_new_mode in ucrt\heap\new_mode.cpp
int _set_new_mode(int flag) {
// The MS CRT calls this function early on in startup, so this serves as a low
// overhead proof that the allocator shim is in place for this process.
base::allocator::g_is_win_shim_layer_initialized = true;
int old_mode = win_new_mode;
win_new_mode = flag;
base::allocator::SetCallNewHandlerOnMallocFailure(win_new_mode != 0);
return old_mode;
}
// Replaces _query_new_mode in ucrt\heap\new_mode.cpp
int _query_new_mode() {
return win_new_mode;
}
// These symbols override the CRT's implementation of the same functions.
__declspec(restrict) void* malloc(size_t size) {
return ShimMalloc(size, nullptr);
}
void free(void* ptr) {
ShimFree(ptr, nullptr);
}
__declspec(restrict) void* realloc(void* ptr, size_t size) {
return ShimRealloc(ptr, size, nullptr);
}
__declspec(restrict) void* calloc(size_t n, size_t size) {
return ShimCalloc(n, size, nullptr);
}
// _msize() is the Windows equivalent of malloc_size().
size_t _msize(void* memblock) {
return ShimGetSizeEstimate(memblock, nullptr);
}
__declspec(restrict) void* _aligned_malloc(size_t size, size_t alignment) {
return ShimAlignedMalloc(size, alignment, nullptr);
}
__declspec(restrict) void* _aligned_realloc(void* address,
size_t size,
size_t alignment) {
return ShimAlignedRealloc(address, size, alignment, nullptr);
}
void _aligned_free(void* address) {
ShimAlignedFree(address, nullptr);
}
// _recalloc_base is called by CRT internally.
__declspec(restrict) void* _recalloc_base(void* block,
size_t count,
size_t size) {
const size_t old_block_size = (block != nullptr) ? _msize(block) : 0;
base::CheckedNumeric<size_t> new_block_size_checked = count;
new_block_size_checked *= size;
const size_t new_block_size = new_block_size_checked.ValueOrDie();
void* const new_block = realloc(block, new_block_size);
if (new_block != nullptr && old_block_size < new_block_size) {
memset(static_cast<char*>(new_block) + old_block_size, 0,
new_block_size - old_block_size);
}
return new_block;
}
__declspec(restrict) void* _malloc_base(size_t size) {
return malloc(size);
}
__declspec(restrict) void* _calloc_base(size_t n, size_t size) {
return calloc(n, size);
}
void _free_base(void* block) {
free(block);
}
__declspec(restrict) void* _recalloc(void* block, size_t count, size_t size) {
return _recalloc_base(block, count, size);
}
// The following uncommon _aligned_* routines are not used in Chromium and have
// been shimmed to immediately crash to ensure that implementations are added if
// uses are introduced.
__declspec(restrict) void* _aligned_recalloc(void* address,
size_t num,
size_t size,
size_t alignment) {
CHECK(false) << "This routine has not been implemented";
__builtin_unreachable();
}
size_t _aligned_msize(void* address, size_t alignment, size_t offset) {
CHECK(false) << "This routine has not been implemented";
__builtin_unreachable();
}
__declspec(restrict) void* _aligned_offset_malloc(size_t size,
size_t alignment,
size_t offset) {
CHECK(false) << "This routine has not been implemented";
__builtin_unreachable();
}
__declspec(restrict) void* _aligned_offset_realloc(void* address,
size_t size,
size_t alignment,
size_t offset) {
CHECK(false) << "This routine has not been implemented";
__builtin_unreachable();
}
__declspec(restrict) void* _aligned_offset_recalloc(void* address,
size_t num,
size_t size,
size_t alignment,
size_t offset) {
CHECK(false) << "This routine has not been implemented";
__builtin_unreachable();
}
} // extern "C"
#endif // BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_UCRT_SYMBOLS_WIN_H_

View File

@ -0,0 +1,628 @@
// Copyright 2016 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/allocator/allocator_shim.h"
#include <stdlib.h>
#include <string.h>
#include <atomic>
#include <memory>
#include <new>
#include <vector>
#include "base/allocator/buildflags.h"
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/process/process_metrics.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_local.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
#include <malloc.h>
#include <windows.h>
#elif defined(OS_APPLE)
#include <malloc/malloc.h>
#include "base/allocator/allocator_interception_mac.h"
#include "base/mac/mac_util.h"
#include "third_party/apple_apsl/malloc.h"
#else
#include <malloc.h>
#endif
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#if defined(LIBC_GLIBC)
extern "C" void* __libc_memalign(size_t align, size_t s);
#endif
namespace base {
namespace allocator {
namespace {
using testing::_;
using testing::MockFunction;
// Special sentinel values used for testing GetSizeEstimate() interception.
const char kTestSizeEstimateData[] = "test_value";
constexpr void* kTestSizeEstimateAddress = (void*)kTestSizeEstimateData;
constexpr size_t kTestSizeEstimate = 1234;
class AllocatorShimTest : public testing::Test {
public:
AllocatorShimTest() : testing::Test() {}
static size_t Hash(const void* ptr) {
return reinterpret_cast<uintptr_t>(ptr) % MaxSizeTracked();
}
static void* MockAlloc(const AllocatorDispatch* self,
size_t size,
void* context) {
if (instance_ && size < MaxSizeTracked())
++(instance_->allocs_intercepted_by_size[size]);
return self->next->alloc_function(self->next, size, context);
}
static void* MockAllocUnchecked(const AllocatorDispatch* self,
size_t size,
void* context) {
if (instance_ && size < MaxSizeTracked())
++(instance_->allocs_intercepted_by_size[size]);
return self->next->alloc_unchecked_function(self->next, size, context);
}
static void* MockAllocZeroInit(const AllocatorDispatch* self,
size_t n,
size_t size,
void* context) {
const size_t real_size = n * size;
if (instance_ && real_size < MaxSizeTracked())
++(instance_->zero_allocs_intercepted_by_size[real_size]);
return self->next->alloc_zero_initialized_function(self->next, n, size,
context);
}
static void* MockAllocAligned(const AllocatorDispatch* self,
size_t alignment,
size_t size,
void* context) {
if (instance_) {
if (size < MaxSizeTracked())
++(instance_->aligned_allocs_intercepted_by_size[size]);
if (alignment < MaxSizeTracked())
++(instance_->aligned_allocs_intercepted_by_alignment[alignment]);
}
return self->next->alloc_aligned_function(self->next, alignment, size,
context);
}
static void* MockRealloc(const AllocatorDispatch* self,
void* address,
size_t size,
void* context) {
if (instance_) {
// Size 0xFEED a special sentinel for the NewHandlerConcurrency test.
// Hitting it for the first time will cause a failure, causing the
// invocation of the std::new_handler.
if (size == 0xFEED) {
if (!instance_->did_fail_realloc_0xfeed_once->Get()) {
instance_->did_fail_realloc_0xfeed_once->Set(true);
return nullptr;
}
return address;
}
if (size < MaxSizeTracked())
++(instance_->reallocs_intercepted_by_size[size]);
++instance_->reallocs_intercepted_by_addr[Hash(address)];
}
return self->next->realloc_function(self->next, address, size, context);
}
static void MockFree(const AllocatorDispatch* self,
void* address,
void* context) {
if (instance_) {
++instance_->frees_intercepted_by_addr[Hash(address)];
}
self->next->free_function(self->next, address, context);
}
static size_t MockGetSizeEstimate(const AllocatorDispatch* self,
void* address,
void* context) {
// Special testing values for GetSizeEstimate() interception.
if (address == kTestSizeEstimateAddress)
return kTestSizeEstimate;
return self->next->get_size_estimate_function(self->next, address, context);
}
static unsigned MockBatchMalloc(const AllocatorDispatch* self,
size_t size,
void** results,
unsigned num_requested,
void* context) {
if (instance_) {
instance_->batch_mallocs_intercepted_by_size[size] =
instance_->batch_mallocs_intercepted_by_size[size] + num_requested;
}
return self->next->batch_malloc_function(self->next, size, results,
num_requested, context);
}
static void MockBatchFree(const AllocatorDispatch* self,
void** to_be_freed,
unsigned num_to_be_freed,
void* context) {
if (instance_) {
for (unsigned i = 0; i < num_to_be_freed; ++i) {
++instance_->batch_frees_intercepted_by_addr[Hash(to_be_freed[i])];
}
}
self->next->batch_free_function(self->next, to_be_freed, num_to_be_freed,
context);
}
static void MockFreeDefiniteSize(const AllocatorDispatch* self,
void* ptr,
size_t size,
void* context) {
if (instance_) {
++instance_->frees_intercepted_by_addr[Hash(ptr)];
++instance_->free_definite_sizes_intercepted_by_size[size];
}
self->next->free_definite_size_function(self->next, ptr, size, context);
}
static void* MockAlignedMalloc(const AllocatorDispatch* self,
size_t size,
size_t alignment,
void* context) {
if (instance_ && size < MaxSizeTracked()) {
++instance_->aligned_mallocs_intercepted_by_size[size];
}
return self->next->aligned_malloc_function(self->next, size, alignment,
context);
}
static void* MockAlignedRealloc(const AllocatorDispatch* self,
void* address,
size_t size,
size_t alignment,
void* context) {
if (instance_) {
if (size < MaxSizeTracked())
++instance_->aligned_reallocs_intercepted_by_size[size];
++instance_->aligned_reallocs_intercepted_by_addr[Hash(address)];
}
return self->next->aligned_realloc_function(self->next, address, size,
alignment, context);
}
static void MockAlignedFree(const AllocatorDispatch* self,
void* address,
void* context) {
if (instance_) {
++instance_->aligned_frees_intercepted_by_addr[Hash(address)];
}
self->next->aligned_free_function(self->next, address, context);
}
static void NewHandler() {
if (!instance_)
return;
instance_->num_new_handler_calls.fetch_add(1, std::memory_order_relaxed);
}
int32_t GetNumberOfNewHandlerCalls() {
return instance_->num_new_handler_calls.load(std::memory_order_acquire);
}
void SetUp() override {
allocs_intercepted_by_size.resize(MaxSizeTracked());
zero_allocs_intercepted_by_size.resize(MaxSizeTracked());
aligned_allocs_intercepted_by_size.resize(MaxSizeTracked());
aligned_allocs_intercepted_by_alignment.resize(MaxSizeTracked());
reallocs_intercepted_by_size.resize(MaxSizeTracked());
reallocs_intercepted_by_addr.resize(MaxSizeTracked());
frees_intercepted_by_addr.resize(MaxSizeTracked());
batch_mallocs_intercepted_by_size.resize(MaxSizeTracked());
batch_frees_intercepted_by_addr.resize(MaxSizeTracked());
free_definite_sizes_intercepted_by_size.resize(MaxSizeTracked());
aligned_mallocs_intercepted_by_size.resize(MaxSizeTracked());
aligned_reallocs_intercepted_by_size.resize(MaxSizeTracked());
aligned_reallocs_intercepted_by_addr.resize(MaxSizeTracked());
aligned_frees_intercepted_by_addr.resize(MaxSizeTracked());
did_fail_realloc_0xfeed_once = std::make_unique<ThreadLocalBoolean>();
num_new_handler_calls.store(0, std::memory_order_release);
instance_ = this;
#if defined(OS_APPLE)
InitializeAllocatorShim();
#endif
}
void TearDown() override {
instance_ = nullptr;
#if defined(OS_APPLE)
UninterceptMallocZonesForTesting();
#endif
}
static size_t MaxSizeTracked() {
#if defined(OS_IOS)
// TODO(crbug.com/1077271): 64-bit iOS uses a page size that is larger than
// SystemPageSize(), causing this test to make larger allocations, relative
// to SystemPageSize().
return 6 * base::SystemPageSize();
#else
return 2 * base::SystemPageSize();
#endif
}
protected:
std::vector<size_t> allocs_intercepted_by_size;
std::vector<size_t> zero_allocs_intercepted_by_size;
std::vector<size_t> aligned_allocs_intercepted_by_size;
std::vector<size_t> aligned_allocs_intercepted_by_alignment;
std::vector<size_t> reallocs_intercepted_by_size;
std::vector<size_t> reallocs_intercepted_by_addr;
std::vector<size_t> frees_intercepted_by_addr;
std::vector<size_t> batch_mallocs_intercepted_by_size;
std::vector<size_t> batch_frees_intercepted_by_addr;
std::vector<size_t> free_definite_sizes_intercepted_by_size;
std::vector<size_t> aligned_mallocs_intercepted_by_size;
std::vector<size_t> aligned_reallocs_intercepted_by_size;
std::vector<size_t> aligned_reallocs_intercepted_by_addr;
std::vector<size_t> aligned_frees_intercepted_by_addr;
std::unique_ptr<ThreadLocalBoolean> did_fail_realloc_0xfeed_once;
std::atomic<uint32_t> num_new_handler_calls;
private:
static AllocatorShimTest* instance_;
};
struct TestStruct1 {
uint32_t ignored;
uint8_t ignored_2;
};
struct TestStruct2 {
uint64_t ignored;
uint8_t ignored_3;
};
class ThreadDelegateForNewHandlerTest : public PlatformThread::Delegate {
public:
explicit ThreadDelegateForNewHandlerTest(WaitableEvent* event)
: event_(event) {}
void ThreadMain() override {
event_->Wait();
void* temp = malloc(1);
void* res = realloc(temp, 0xFEED);
EXPECT_EQ(temp, res);
}
private:
WaitableEvent* event_;
};
AllocatorShimTest* AllocatorShimTest::instance_ = nullptr;
AllocatorDispatch g_mock_dispatch = {
&AllocatorShimTest::MockAlloc, /* alloc_function */
&AllocatorShimTest::MockAllocUnchecked, /* alloc_unchecked_function */
&AllocatorShimTest::MockAllocZeroInit, /* alloc_zero_initialized_function */
&AllocatorShimTest::MockAllocAligned, /* alloc_aligned_function */
&AllocatorShimTest::MockRealloc, /* realloc_function */
&AllocatorShimTest::MockFree, /* free_function */
&AllocatorShimTest::MockGetSizeEstimate, /* get_size_estimate_function */
&AllocatorShimTest::MockBatchMalloc, /* batch_malloc_function */
&AllocatorShimTest::MockBatchFree, /* batch_free_function */
&AllocatorShimTest::MockFreeDefiniteSize, /* free_definite_size_function */
&AllocatorShimTest::MockAlignedMalloc, /* aligned_malloc_function */
&AllocatorShimTest::MockAlignedRealloc, /* aligned_realloc_function */
&AllocatorShimTest::MockAlignedFree, /* aligned_free_function */
nullptr, /* next */
};
TEST_F(AllocatorShimTest, InterceptLibcSymbols) {
InsertAllocatorDispatch(&g_mock_dispatch);
void* alloc_ptr = malloc(19);
ASSERT_NE(nullptr, alloc_ptr);
ASSERT_GE(allocs_intercepted_by_size[19], 1u);
void* zero_alloc_ptr = calloc(2, 23);
ASSERT_NE(nullptr, zero_alloc_ptr);
ASSERT_GE(zero_allocs_intercepted_by_size[2 * 23], 1u);
#if !defined(OS_WIN)
void* posix_memalign_ptr = nullptr;
int res = posix_memalign(&posix_memalign_ptr, 256, 59);
ASSERT_EQ(0, res);
ASSERT_NE(nullptr, posix_memalign_ptr);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(posix_memalign_ptr) % 256);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[256], 1u);
ASSERT_GE(aligned_allocs_intercepted_by_size[59], 1u);
// (p)valloc() are not defined on Android. pvalloc() is a GNU extension,
// valloc() is not in POSIX.
#if !defined(OS_ANDROID)
const size_t kPageSize = base::GetPageSize();
void* valloc_ptr = valloc(61);
ASSERT_NE(nullptr, valloc_ptr);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(valloc_ptr) % kPageSize);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[kPageSize], 1u);
ASSERT_GE(aligned_allocs_intercepted_by_size[61], 1u);
#endif // !defined(OS_ANDROID)
#endif // !OS_WIN
#if !defined(OS_WIN) && !defined(OS_APPLE)
void* memalign_ptr = memalign(128, 53);
ASSERT_NE(nullptr, memalign_ptr);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(memalign_ptr) % 128);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[128], 1u);
ASSERT_GE(aligned_allocs_intercepted_by_size[53], 1u);
#if !defined(OS_ANDROID)
void* pvalloc_ptr = pvalloc(67);
ASSERT_NE(nullptr, pvalloc_ptr);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(pvalloc_ptr) % kPageSize);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[kPageSize], 1u);
// pvalloc rounds the size up to the next page.
ASSERT_GE(aligned_allocs_intercepted_by_size[kPageSize], 1u);
#endif // !defined(OS_ANDROID)
#endif // !OS_WIN && !OS_APPLE
// See allocator_shim_override_glibc_weak_symbols.h for why we intercept
// internal libc symbols.
#if defined(LIBC_GLIBC) && \
(BUILDFLAG(USE_TCMALLOC) || BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC))
void* libc_memalign_ptr = __libc_memalign(512, 56);
ASSERT_NE(nullptr, memalign_ptr);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(libc_memalign_ptr) % 512);
ASSERT_GE(aligned_allocs_intercepted_by_alignment[512], 1u);
ASSERT_GE(aligned_allocs_intercepted_by_size[56], 1u);
#endif
char* realloc_ptr = static_cast<char*>(malloc(10));
strcpy(realloc_ptr, "foobar");
void* old_realloc_ptr = realloc_ptr;
realloc_ptr = static_cast<char*>(realloc(realloc_ptr, 73));
ASSERT_GE(reallocs_intercepted_by_size[73], 1u);
ASSERT_GE(reallocs_intercepted_by_addr[Hash(old_realloc_ptr)], 1u);
ASSERT_EQ(0, strcmp(realloc_ptr, "foobar"));
free(alloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(alloc_ptr)], 1u);
free(zero_alloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(zero_alloc_ptr)], 1u);
#if !defined(OS_WIN) && !defined(OS_APPLE)
free(memalign_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(memalign_ptr)], 1u);
#if !defined(OS_ANDROID)
free(pvalloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(pvalloc_ptr)], 1u);
#endif // !defined(OS_ANDROID)
#endif // !OS_WIN && !OS_APPLE
#if !defined(OS_WIN)
free(posix_memalign_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(posix_memalign_ptr)], 1u);
#if !defined(OS_ANDROID)
free(valloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(valloc_ptr)], 1u);
#endif // !defined(OS_ANDROID)
#endif // !OS_WIN
#if defined(LIBC_GLIBC) && \
(BUILDFLAG(USE_TCMALLOC) || BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC))
free(libc_memalign_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(memalign_ptr)], 1u);
#endif
free(realloc_ptr);
ASSERT_GE(frees_intercepted_by_addr[Hash(realloc_ptr)], 1u);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
void* non_hooked_ptr = malloc(4095);
ASSERT_NE(nullptr, non_hooked_ptr);
ASSERT_EQ(0u, allocs_intercepted_by_size[4095]);
free(non_hooked_ptr);
}
#if defined(OS_APPLE)
TEST_F(AllocatorShimTest, InterceptLibcSymbolsBatchMallocFree) {
InsertAllocatorDispatch(&g_mock_dispatch);
unsigned count = 13;
std::vector<void*> results;
results.resize(count);
unsigned result_count = malloc_zone_batch_malloc(malloc_default_zone(), 99,
results.data(), count);
ASSERT_EQ(count, result_count);
// TODO(erikchen): On macOS 10.12+, batch_malloc in the default zone may
// forward to another zone, which we've also shimmed, resulting in
// MockBatchMalloc getting called twice as often as we'd expect. This
// re-entrancy into the allocator shim is a bug that needs to be fixed.
// https://crbug.com/693237.
// ASSERT_EQ(count, batch_mallocs_intercepted_by_size[99]);
std::vector<void*> results_copy(results);
malloc_zone_batch_free(malloc_default_zone(), results.data(), count);
for (void* result : results_copy) {
ASSERT_GE(batch_frees_intercepted_by_addr[Hash(result)], 1u);
}
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
}
TEST_F(AllocatorShimTest, InterceptLibcSymbolsFreeDefiniteSize) {
InsertAllocatorDispatch(&g_mock_dispatch);
void* alloc_ptr = malloc(19);
ASSERT_NE(nullptr, alloc_ptr);
ASSERT_GE(allocs_intercepted_by_size[19], 1u);
ChromeMallocZone* default_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
default_zone->free_definite_size(malloc_default_zone(), alloc_ptr, 19);
ASSERT_GE(free_definite_sizes_intercepted_by_size[19], 1u);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
}
#endif // defined(OS_APPLE)
#if defined(OS_WIN)
TEST_F(AllocatorShimTest, InterceptUcrtAlignedAllocationSymbols) {
InsertAllocatorDispatch(&g_mock_dispatch);
constexpr size_t kAlignment = 32;
void* alloc_ptr = _aligned_malloc(123, kAlignment);
EXPECT_GE(aligned_mallocs_intercepted_by_size[123], 1u);
void* new_alloc_ptr = _aligned_realloc(alloc_ptr, 1234, kAlignment);
EXPECT_GE(aligned_reallocs_intercepted_by_size[1234], 1u);
EXPECT_GE(aligned_reallocs_intercepted_by_addr[Hash(alloc_ptr)], 1u);
_aligned_free(new_alloc_ptr);
EXPECT_GE(aligned_frees_intercepted_by_addr[Hash(new_alloc_ptr)], 1u);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
}
TEST_F(AllocatorShimTest, AlignedReallocSizeZeroFrees) {
void* alloc_ptr = _aligned_malloc(123, 16);
CHECK(alloc_ptr);
alloc_ptr = _aligned_realloc(alloc_ptr, 0, 16);
CHECK(!alloc_ptr);
}
#endif // defined(OS_WIN)
TEST_F(AllocatorShimTest, InterceptCppSymbols) {
InsertAllocatorDispatch(&g_mock_dispatch);
TestStruct1* new_ptr = new TestStruct1;
ASSERT_NE(nullptr, new_ptr);
ASSERT_GE(allocs_intercepted_by_size[sizeof(TestStruct1)], 1u);
TestStruct1* new_array_ptr = new TestStruct1[3];
ASSERT_NE(nullptr, new_array_ptr);
ASSERT_GE(allocs_intercepted_by_size[sizeof(TestStruct1) * 3], 1u);
TestStruct2* new_nt_ptr = new (std::nothrow) TestStruct2;
ASSERT_NE(nullptr, new_nt_ptr);
ASSERT_GE(allocs_intercepted_by_size[sizeof(TestStruct2)], 1u);
TestStruct2* new_array_nt_ptr = new TestStruct2[3];
ASSERT_NE(nullptr, new_array_nt_ptr);
ASSERT_GE(allocs_intercepted_by_size[sizeof(TestStruct2) * 3], 1u);
delete new_ptr;
ASSERT_GE(frees_intercepted_by_addr[Hash(new_ptr)], 1u);
delete[] new_array_ptr;
ASSERT_GE(frees_intercepted_by_addr[Hash(new_array_ptr)], 1u);
delete new_nt_ptr;
ASSERT_GE(frees_intercepted_by_addr[Hash(new_nt_ptr)], 1u);
delete[] new_array_nt_ptr;
ASSERT_GE(frees_intercepted_by_addr[Hash(new_array_nt_ptr)], 1u);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
}
// This test exercises the case of concurrent OOM failure, which would end up
// invoking std::new_handler concurrently. This is to cover the CallNewHandler()
// paths of allocator_shim.cc and smoke-test its thread safey.
// The test creates kNumThreads threads. Each of them mallocs some memory, and
// then does a realloc(<new memory>, 0xFEED).
// The shim intercepts such realloc and makes it fail only once on each thread.
// We expect to see excactly kNumThreads invocations of the new_handler.
TEST_F(AllocatorShimTest, NewHandlerConcurrency) {
const int kNumThreads = 32;
PlatformThreadHandle threads[kNumThreads];
// The WaitableEvent here is used to attempt to trigger all the threads at
// the same time, after they have been initialized.
WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED);
ThreadDelegateForNewHandlerTest mock_thread_main(&event);
for (int i = 0; i < kNumThreads; ++i)
PlatformThread::Create(0, &mock_thread_main, &threads[i]);
std::set_new_handler(&AllocatorShimTest::NewHandler);
SetCallNewHandlerOnMallocFailure(true); // It's going to fail on realloc().
InsertAllocatorDispatch(&g_mock_dispatch);
event.Signal();
for (int i = 0; i < kNumThreads; ++i)
PlatformThread::Join(threads[i]);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
ASSERT_EQ(kNumThreads, GetNumberOfNewHandlerCalls());
}
#if defined(OS_WIN) && BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST_F(AllocatorShimTest, ShimReplacesCRTHeapWhenEnabled) {
ASSERT_EQ(::GetProcessHeap(), reinterpret_cast<HANDLE>(_get_heap_handle()));
}
#endif // defined(OS_WIN) && BUILDFLAG(USE_ALLOCATOR_SHIM)
#if defined(OS_WIN)
static size_t GetAllocatedSize(void* ptr) {
return _msize(ptr);
}
#elif defined(OS_APPLE)
static size_t GetAllocatedSize(void* ptr) {
return malloc_size(ptr);
}
#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
static size_t GetAllocatedSize(void* ptr) {
return malloc_usable_size(ptr);
}
#else
#define NO_MALLOC_SIZE
#endif
#if !defined(NO_MALLOC_SIZE) && BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST_F(AllocatorShimTest, ShimReplacesMallocSizeWhenEnabled) {
InsertAllocatorDispatch(&g_mock_dispatch);
EXPECT_EQ(GetAllocatedSize(kTestSizeEstimateAddress), kTestSizeEstimate);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
}
TEST_F(AllocatorShimTest, ShimDoesntChangeMallocSizeWhenEnabled) {
void* alloc = malloc(16);
size_t sz = GetAllocatedSize(alloc);
EXPECT_GE(sz, 16U);
InsertAllocatorDispatch(&g_mock_dispatch);
EXPECT_EQ(GetAllocatedSize(alloc), sz);
RemoveAllocatorDispatchForTesting(&g_mock_dispatch);
free(alloc);
}
#endif // !defined(NO_MALLOC_SIZE) && BUILDFLAG(USE_ALLOCATOR_SHIM)
} // namespace
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,21 @@
// Copyright (c) 2012 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.
// Workaround for crosbug:629593. Using AFDO on the tcmalloc files is
// causing problems. The tcmalloc files depend on stack layouts and
// AFDO can mess with them. Better not to use AFDO there. This is a
// temporary hack. We will add a mechanism in the build system to
// avoid using -fauto-profile for tcmalloc files.
#if !defined(__clang__) && \
(defined(OS_CHROMEOS) || (__GNUC__ > 5 && __GNUC__ < 7))
// Note that this option only seems to be available in the chromeos GCC 4.9
// toolchain, and stock GCC 5 upto 7.
#pragma GCC optimize ("no-auto-profile")
#endif
#if defined(TCMALLOC_FOR_DEBUGALLOCATION)
#include "third_party/tcmalloc/chromium/src/debugallocation.cc"
#else
#include "third_party/tcmalloc/chromium/src/tcmalloc.cc"
#endif

View File

@ -0,0 +1,119 @@
// Copyright 2017 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/allocator/malloc_zone_functions_mac.h"
#include <atomic>
#include "base/synchronization/lock.h"
namespace base {
namespace allocator {
MallocZoneFunctions g_malloc_zones[kMaxZoneCount];
static_assert(std::is_pod<MallocZoneFunctions>::value,
"MallocZoneFunctions must be POD");
void StoreZoneFunctions(const ChromeMallocZone* zone,
MallocZoneFunctions* functions) {
memset(functions, 0, sizeof(MallocZoneFunctions));
functions->malloc = zone->malloc;
functions->calloc = zone->calloc;
functions->valloc = zone->valloc;
functions->free = zone->free;
functions->realloc = zone->realloc;
functions->size = zone->size;
CHECK(functions->malloc && functions->calloc && functions->valloc &&
functions->free && functions->realloc && functions->size);
// These functions might be nullptr.
functions->batch_malloc = zone->batch_malloc;
functions->batch_free = zone->batch_free;
if (zone->version >= 5) {
// Not all custom malloc zones have a memalign.
functions->memalign = zone->memalign;
}
if (zone->version >= 6) {
// This may be nullptr.
functions->free_definite_size = zone->free_definite_size;
}
// Note that zone version 8 introduced a pressure relief callback, and version
// 10 introduced a claimed address callback, but neither are allocation or
// deallocation callbacks and so aren't important to intercept.
functions->context = zone;
}
namespace {
// All modifications to g_malloc_zones are gated behind this lock.
// Dispatch to a malloc zone does not need to acquire this lock.
base::Lock& GetLock() {
static base::Lock* g_lock = new base::Lock;
return *g_lock;
}
void EnsureMallocZonesInitializedLocked() {
GetLock().AssertAcquired();
}
int g_zone_count = 0;
bool IsMallocZoneAlreadyStoredLocked(ChromeMallocZone* zone) {
EnsureMallocZonesInitializedLocked();
GetLock().AssertAcquired();
for (int i = 0; i < g_zone_count; ++i) {
if (g_malloc_zones[i].context == reinterpret_cast<void*>(zone))
return true;
}
return false;
}
} // namespace
bool StoreMallocZone(ChromeMallocZone* zone) {
base::AutoLock l(GetLock());
EnsureMallocZonesInitializedLocked();
if (IsMallocZoneAlreadyStoredLocked(zone))
return false;
if (g_zone_count == kMaxZoneCount)
return false;
StoreZoneFunctions(zone, &g_malloc_zones[g_zone_count]);
++g_zone_count;
// No other thread can possibly see these stores at this point. The code that
// reads these values is triggered after this function returns. so we want to
// guarantee that they are committed at this stage"
std::atomic_thread_fence(std::memory_order_seq_cst);
return true;
}
bool IsMallocZoneAlreadyStored(ChromeMallocZone* zone) {
base::AutoLock l(GetLock());
return IsMallocZoneAlreadyStoredLocked(zone);
}
bool DoesMallocZoneNeedReplacing(ChromeMallocZone* zone,
const MallocZoneFunctions* functions) {
return IsMallocZoneAlreadyStored(zone) && zone->malloc != functions->malloc;
}
int GetMallocZoneCountForTesting() {
base::AutoLock l(GetLock());
return g_zone_count;
}
void ClearAllMallocZonesForTesting() {
base::AutoLock l(GetLock());
EnsureMallocZonesInitializedLocked();
memset(g_malloc_zones, 0, kMaxZoneCount * sizeof(MallocZoneFunctions));
g_zone_count = 0;
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,103 @@
// Copyright 2017 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_ALLOCATOR_MALLOC_ZONE_FUNCTIONS_MAC_H_
#define BASE_ALLOCATOR_MALLOC_ZONE_FUNCTIONS_MAC_H_
#include <malloc/malloc.h>
#include <stddef.h>
#include "base/base_export.h"
#include "base/immediate_crash.h"
#include "third_party/apple_apsl/malloc.h"
namespace base {
namespace allocator {
typedef void* (*malloc_type)(struct _malloc_zone_t* zone, size_t size);
typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
size_t num_items,
size_t size);
typedef void* (*valloc_type)(struct _malloc_zone_t* zone, size_t size);
typedef void (*free_type)(struct _malloc_zone_t* zone, void* ptr);
typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
void* ptr,
size_t size);
typedef void* (*memalign_type)(struct _malloc_zone_t* zone,
size_t alignment,
size_t size);
typedef unsigned (*batch_malloc_type)(struct _malloc_zone_t* zone,
size_t size,
void** results,
unsigned num_requested);
typedef void (*batch_free_type)(struct _malloc_zone_t* zone,
void** to_be_freed,
unsigned num_to_be_freed);
typedef void (*free_definite_size_type)(struct _malloc_zone_t* zone,
void* ptr,
size_t size);
typedef size_t (*size_fn_type)(struct _malloc_zone_t* zone, const void* ptr);
struct MallocZoneFunctions {
malloc_type malloc;
calloc_type calloc;
valloc_type valloc;
free_type free;
realloc_type realloc;
memalign_type memalign;
batch_malloc_type batch_malloc;
batch_free_type batch_free;
free_definite_size_type free_definite_size;
size_fn_type size;
const ChromeMallocZone* context;
};
BASE_EXPORT void StoreZoneFunctions(const ChromeMallocZone* zone,
MallocZoneFunctions* functions);
static constexpr int kMaxZoneCount = 30;
BASE_EXPORT extern MallocZoneFunctions g_malloc_zones[kMaxZoneCount];
// The array g_malloc_zones stores all information about malloc zones before
// they are shimmed. This information needs to be accessed during dispatch back
// into the zone, and additional zones may be added later in the execution fo
// the program, so the array needs to be both thread-safe and high-performance.
//
// We begin by creating an array of MallocZoneFunctions of fixed size. We will
// never modify the container, which provides thread-safety to iterators. When
// we want to add a MallocZoneFunctions to the container, we:
// 1. Fill in all the fields.
// 2. Update the total zone count.
// 3. Insert a memory barrier.
// 4. Insert our shim.
//
// Each MallocZoneFunctions is uniquely identified by |context|, which is a
// pointer to the original malloc zone. When we wish to dispatch back to the
// original malloc zones, we iterate through the array, looking for a matching
// |context|.
//
// Most allocations go through the default allocator. We will ensure that the
// default allocator is stored as the first MallocZoneFunctions.
//
// Returns whether the zone was successfully stored.
BASE_EXPORT bool StoreMallocZone(ChromeMallocZone* zone);
BASE_EXPORT bool IsMallocZoneAlreadyStored(ChromeMallocZone* zone);
BASE_EXPORT bool DoesMallocZoneNeedReplacing(
ChromeMallocZone* zone,
const MallocZoneFunctions* functions);
BASE_EXPORT int GetMallocZoneCountForTesting();
BASE_EXPORT void ClearAllMallocZonesForTesting();
inline MallocZoneFunctions& GetFunctionsForZone(void* zone) {
for (unsigned int i = 0; i < kMaxZoneCount; ++i) {
if (g_malloc_zones[i].context == zone)
return g_malloc_zones[i];
}
IMMEDIATE_CRASH();
}
} // namespace allocator
} // namespace base
#endif // BASE_ALLOCATOR_MALLOC_ZONE_FUNCTIONS_MAC_H_

View File

@ -0,0 +1,57 @@
// Copyright 2017 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/allocator/malloc_zone_functions_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace allocator {
class MallocZoneFunctionsTest : public testing::Test {
protected:
void TearDown() override { ClearAllMallocZonesForTesting(); }
};
TEST_F(MallocZoneFunctionsTest, TestDefaultZoneMallocFree) {
ChromeMallocZone* malloc_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
StoreMallocZone(malloc_zone);
int* test = reinterpret_cast<int*>(
g_malloc_zones[0].malloc(malloc_default_zone(), 33));
test[0] = 1;
test[1] = 2;
g_malloc_zones[0].free(malloc_default_zone(), test);
}
TEST_F(MallocZoneFunctionsTest, IsZoneAlreadyStored) {
ChromeMallocZone* malloc_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
EXPECT_FALSE(IsMallocZoneAlreadyStored(malloc_zone));
StoreMallocZone(malloc_zone);
EXPECT_TRUE(IsMallocZoneAlreadyStored(malloc_zone));
}
TEST_F(MallocZoneFunctionsTest, CannotDoubleStoreZone) {
ChromeMallocZone* malloc_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
StoreMallocZone(malloc_zone);
StoreMallocZone(malloc_zone);
EXPECT_EQ(1, GetMallocZoneCountForTesting());
}
TEST_F(MallocZoneFunctionsTest, CannotStoreMoreThanMaxZones) {
std::vector<ChromeMallocZone> zones;
zones.resize(kMaxZoneCount * 2);
for (int i = 0; i < kMaxZoneCount * 2; ++i) {
ChromeMallocZone& zone = zones[i];
memcpy(&zone, malloc_default_zone(), sizeof(ChromeMallocZone));
StoreMallocZone(&zone);
}
int max_zone_count = kMaxZoneCount;
EXPECT_EQ(max_zone_count, GetMallocZoneCountForTesting());
}
} // namespace allocator
} // namespace base

View File

@ -0,0 +1,9 @@
ajwong@chromium.org
haraken@chromium.org
lizeb@chromium.org
palmer@chromium.org
tsepez@chromium.org
# TEAM: platform-architecture-dev@chromium.org
# Also: security-dev@chromium.org
# COMPONENT: Blink>MemoryAllocator>Partition

View File

@ -0,0 +1,113 @@
# PartitionAlloc Design
This document describes PartitionAlloc at a high level. For documentation about
its implementation, see the comments in `partition_alloc.h`.
[TOC]
## Overview
PartitionAlloc is a memory allocator optimized for security, low allocation
latency (when called appropriately), and good space efficiency (when called
appropriately). This document aims to help you understand how PartitionAlloc
works so that you can use it effectively.
## Partitions And Buckets
A *partition* is a heap that contains certain object types, objects of certain
sizes, or objects of a certain lifetime (as the caller prefers). Callers can
create as many partitions as they need. Each partition is separate and protected
from any other partitions.
Each partition holds multiple buckets. A *bucket* is a region in a partition
that contains similar-sized objects.
PartitionAlloc aligns each object allocation with the closest bucket size. For
example, if a partition has 3 buckets for 64 bytes, 256 bytes, and 1024 bytes,
then PartitionAlloc will satisfy an allocation request for 128 bytes by rounding
it up to 256 bytes and allocating from the second bucket.
## Performance
The current implementation is optimized for the main thread use-case. For
example, PartitionAlloc doesn't have threaded caches.
PartitionAlloc is designed to be extremely fast in its fast paths. The fast
paths of allocation and deallocation require just 2 (reasonably predictable)
branches. The number of operations in the fast paths is minimal, leading to the
possibility of inlining.
For an example of how to use partitions to get good performance and good safety,
see Blink's usage, as described in `wtf/allocator/Allocator.md`.
Large allocations (> kMaxBucketed == 960KB) are realized by direct
memory mmapping. This size makes sense because 960KB = 0xF0000. The next larger
bucket size is 1MB = 0x100000 which is greater than 1/2 the available space in
a SuperPage meaning it would not be possible to pack even 2 sequential
allocations in a SuperPage.
`PartitionRoot<internal::ThreadSafe>::Alloc()` acquires a lock for thread
safety. (The current implementation uses a spin lock on the assumption that
thread contention will be rare in its callers. The original caller was Blink,
where this is generally true. Spin locks also have the benefit of simplicity.)
Callers can get thread-unsafe performance using a
`PartitionRoot<internal::NotThreadSafe>::Alloc()` or otherwise using
`PartitionAlloc<internal::NotThreadSafe>`. Callers can also arrange for low
contention, such as by using a dedicated partition for single-threaded,
latency-critical allocations.
Because PartitionAlloc guarantees that address space regions used for one
partition are never reused for other partitions, partitions can eat a large
amount of virtual address space (even if not of actual memory).
Mixing various random objects in the same partition will generally lead to lower
efficiency. For good performance, group similar objects into the same partition.
## Security
Security is one of the most important goals of PartitionAlloc.
PartitionAlloc guarantees that different partitions exist in different regions
of the process' address space. When the caller has freed all objects contained
in a page in a partition, PartitionAlloc returns the physical memory to the
operating system, but continues to reserve the region of address space.
PartitionAlloc will only reuse an address space region for the same partition.
PartitionAlloc also guarantees that:
* Linear overflows cannot corrupt into the partition. (There is a guard page at
the beginning of each partition.)
* Linear overflows cannot corrupt out of the partition. (There is a guard page
at the end of each partition.)
* Linear overflow or underflow cannot corrupt the allocation metadata.
PartitionAlloc records metadata in a dedicated region out-of-line (not adjacent
to objects).
* Objects of different sizes will likely be allocated in different buckets, and
hence at different addresses. One page can contain only similar-sized objects.
* Dereference of a freelist pointer should fault.
* Partial pointer overwrite of freelist pointer should fault.
* Large allocations have guard pages at the beginning and end.
## Alignment
PartitionAlloc doesn't have explicit support for a `posix_memalign()` type call,
however it provides some guarantees on the alignment of returned pointers.
All pointers are aligned on the smallest allocation granularity, namely
`sizeof(void*)`. Additionally, for power-of-two sized allocations, the behavior
depends on the compilation flags:
* With `DCHECK_IS_ON()`, returned pointers are never guaranteed to be aligned on
more than 16 bytes.
* Otherwise, the returned pointer is guaranteed to be aligned on
`min(allocation_size, system page size)`.
See the tests in `partition_alloc_unittest.cc` for more details.

View File

@ -0,0 +1,226 @@
// Copyright 2020 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/allocator/partition_allocator/address_pool_manager.h"
#if defined(OS_APPLE)
#include <sys/mman.h>
#endif
#include <algorithm>
#include <limits>
#include "base/allocator/partition_allocator/page_allocator.h"
#include "base/allocator/partition_allocator/page_allocator_internal.h"
#include "base/allocator/partition_allocator/partition_alloc_check.h"
#include "base/bits.h"
#include "base/lazy_instance.h"
#include "base/notreached.h"
#include "base/stl_util.h"
namespace base {
namespace internal {
#if defined(PA_HAS_64_BITS_POINTERS)
namespace {
void DecommitPages(void* address, size_t size) {
#if defined(OS_APPLE)
// MAP_FIXED replaces an existing mapping with a new one, when the address is
// already part of a mapping. Since newly-created mappings are guaranteed to
// be zero-filled, this has the desired effect. It is only required on macOS,
// as on other operating systems, |DecommitSystemPages()| provides the same
// behavior.
void* ptr = mmap(address, size, PROT_NONE,
MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
PA_CHECK(ptr == address);
#else
SetSystemPagesAccess(address, size, PageInaccessible);
DecommitSystemPages(address, size);
#endif
}
bool WARN_UNUSED_RESULT CommitPages(void* address, size_t size) {
#if defined(OS_APPLE)
SetSystemPagesAccess(address, size, PageReadWrite);
#else
if (!RecommitSystemPages(address, size, PageReadWrite))
return false;
SetSystemPagesAccess(address, size, PageReadWrite);
#endif
return true;
}
base::LazyInstance<AddressPoolManager>::Leaky g_address_pool_manager =
LAZY_INSTANCE_INITIALIZER;
} // namespace
constexpr size_t AddressPoolManager::Pool::kMaxBits;
// static
AddressPoolManager* AddressPoolManager::GetInstance() {
return g_address_pool_manager.Pointer();
}
pool_handle AddressPoolManager::Add(uintptr_t ptr, size_t length) {
PA_DCHECK(!(ptr & kSuperPageOffsetMask));
PA_DCHECK(!((ptr + length) & kSuperPageOffsetMask));
for (pool_handle i = 0; i < base::size(pools_); ++i) {
if (!pools_[i].IsInitialized()) {
pools_[i].Initialize(ptr, length);
return i + 1;
}
}
NOTREACHED();
return 0;
}
void AddressPoolManager::ResetForTesting() {
for (pool_handle i = 0; i < base::size(pools_); ++i)
pools_[i].Reset();
}
void AddressPoolManager::Remove(pool_handle handle) {
Pool* pool = GetPool(handle);
PA_DCHECK(pool->IsInitialized());
pool->Reset();
}
char* AddressPoolManager::Alloc(pool_handle handle, size_t length) {
Pool* pool = GetPool(handle);
char* ptr = reinterpret_cast<char*>(pool->FindChunk(length));
if (UNLIKELY(!ptr) || !CommitPages(ptr, length))
return nullptr;
return ptr;
}
void AddressPoolManager::Free(pool_handle handle, void* ptr, size_t length) {
PA_DCHECK(0 < handle && handle <= kNumPools);
Pool* pool = GetPool(handle);
PA_DCHECK(pool->IsInitialized());
DecommitPages(ptr, length);
pool->FreeChunk(reinterpret_cast<uintptr_t>(ptr), length);
}
void AddressPoolManager::Pool::Initialize(uintptr_t ptr, size_t length) {
PA_CHECK(ptr != 0);
PA_CHECK(!(ptr & kSuperPageOffsetMask));
PA_CHECK(!(length & kSuperPageOffsetMask));
address_begin_ = ptr;
#if DCHECK_IS_ON()
address_end_ = ptr + length;
PA_DCHECK(address_begin_ < address_end_);
#endif
total_bits_ = length / kSuperPageSize;
PA_CHECK(total_bits_ <= kMaxBits);
base::AutoLock scoped_lock(lock_);
alloc_bitset_.reset();
bit_hint_ = 0;
}
bool AddressPoolManager::Pool::IsInitialized() {
return address_begin_ != 0;
}
void AddressPoolManager::Pool::Reset() {
address_begin_ = 0;
}
uintptr_t AddressPoolManager::Pool::FindChunk(size_t requested_size) {
base::AutoLock scoped_lock(lock_);
const size_t required_size = bits::Align(requested_size, kSuperPageSize);
const size_t need_bits = required_size >> kSuperPageShift;
// Use first-fit policy to find an available chunk from free chunks. Start
// from |bit_hint_|, because we know there are no free chunks before.
size_t beg_bit = bit_hint_;
size_t curr_bit = bit_hint_;
while (true) {
// |end_bit| points 1 past the last bit that needs to be 0. If it goes past
// |total_bits_|, return |nullptr| to signal no free chunk was found.
size_t end_bit = beg_bit + need_bits;
if (end_bit > total_bits_)
return 0;
bool found = true;
for (; curr_bit < end_bit; ++curr_bit) {
if (alloc_bitset_.test(curr_bit)) {
// The bit was set, so this chunk isn't entirely free. Set |found=false|
// to ensure the outer loop continues. However, continue the inner loop
// to set |beg_bit| just past the last set bit in the investigated
// chunk. |curr_bit| is advanced all the way to |end_bit| to prevent the
// next outer loop pass from checking the same bits.
beg_bit = curr_bit + 1;
found = false;
if (bit_hint_ == curr_bit)
++bit_hint_;
}
}
// An entire [beg_bit;end_bit) region of 0s was found. Fill them with 1s (to
// mark as allocated) and return the allocated address.
if (found) {
for (size_t i = beg_bit; i < end_bit; ++i) {
PA_DCHECK(!alloc_bitset_.test(i));
alloc_bitset_.set(i);
}
if (bit_hint_ == beg_bit) {
bit_hint_ = end_bit;
}
uintptr_t address = address_begin_ + beg_bit * kSuperPageSize;
#if DCHECK_IS_ON()
PA_DCHECK(address + required_size <= address_end_);
#endif
return address;
}
}
NOTREACHED();
return 0;
}
void AddressPoolManager::Pool::FreeChunk(uintptr_t address, size_t free_size) {
base::AutoLock scoped_lock(lock_);
PA_DCHECK(!(address & kSuperPageOffsetMask));
const size_t size = bits::Align(free_size, kSuperPageSize);
DCHECK_LE(address_begin_, address);
#if DCHECK_IS_ON()
PA_DCHECK(address + size <= address_end_);
#endif
const size_t beg_bit = (address - address_begin_) / kSuperPageSize;
const size_t end_bit = beg_bit + size / kSuperPageSize;
for (size_t i = beg_bit; i < end_bit; ++i) {
PA_DCHECK(alloc_bitset_.test(i));
alloc_bitset_.reset(i);
}
bit_hint_ = std::min(bit_hint_, beg_bit);
}
AddressPoolManager::Pool::Pool() = default;
AddressPoolManager::Pool::~Pool() = default;
AddressPoolManager::AddressPoolManager() = default;
AddressPoolManager::~AddressPoolManager() = default;
ALWAYS_INLINE AddressPoolManager::Pool* AddressPoolManager::GetPool(
pool_handle handle) {
PA_DCHECK(0 < handle && handle <= kNumPools);
return &pools_[handle - 1];
}
#endif // defined(PA_HAS_64_BITS_POINTERS)
} // namespace internal
} // namespace base

Some files were not shown because too many files have changed in this diff Show More