mirror of
https://github.com/Alex313031/thorium.git
synced 2025-01-10 03:47:44 -03:00
Add files via upload
This commit is contained in:
parent
e9949692a1
commit
6642d36c48
19 changed files with 9985 additions and 0 deletions
39
src/ash/resources/vector_icons/files_app.icon
Normal file
39
src/ash/resources/vector_icons/files_app.icon
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2022 The Chromium Authors and Alex313031. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
CANVAS_DIMENSIONS, 192,
|
||||
PATH_COLOR_ARGB, 0xFF, 0x1A, 0x73, 0xE8,
|
||||
CIRCLE, 96, 96, 96,
|
||||
NEW_PATH,
|
||||
PATH_COLOR_ARGB, 0xFF, 0x00, 0x00, 0x00,
|
||||
MOVE_TO, 149, 67,
|
||||
CUBIC_TO, 149, 62.58f, 145.42f, 59, 141, 59,
|
||||
LINE_TO, 50, 59,
|
||||
CUBIC_TO, 45.58f, 59, 42, 62.58f, 42, 67,
|
||||
LINE_TO, 42, 132,
|
||||
CUBIC_TO, 42, 136.42f, 45.58f, 140, 50, 140,
|
||||
LINE_TO, 141, 140,
|
||||
CUBIC_TO, 145.42f, 140, 149, 136.42f, 149, 132,
|
||||
LINE_TO, 149, 67,
|
||||
NEW_PATH,
|
||||
PATH_COLOR_ARGB, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
MOVE_TO, 50, 52,
|
||||
CUBIC_TO, 45.58f, 52, 42, 55.58f, 42, 60,
|
||||
V_LINE_TO, 132,
|
||||
CUBIC_TO, 42, 136.42f, 45.58f, 140, 50, 140,
|
||||
H_LINE_TO, 141.13f,
|
||||
CUBIC_TO, 145.55f, 140, 149.13f, 136.42f, 149.13f, 132,
|
||||
V_LINE_TO, 125.13f,
|
||||
LINE_TO, 76, 52,
|
||||
H_LINE_TO, 50,
|
||||
NEW_PATH,
|
||||
PATH_COLOR_ARGB, 0xFF, 0x80, 0xF9, 0xF9,
|
||||
R_MOVE_TO, 149, 77,
|
||||
R_CUBIC_TO, 0, -4.42f, -3.58f, -8, -8, -8,
|
||||
R_H_LINE_TO, -99,
|
||||
R_V_LINE_TO, 63,
|
||||
R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8,
|
||||
R_H_LINE_TO, 91,
|
||||
R_CUBIC_TO, 4.42f, 0, 8, -3.58f, 8, -8,
|
||||
CLOSE
|
45
src/ash/resources/vector_icons/system_menu_info.icon
Normal file
45
src/ash/resources/vector_icons/system_menu_info.icon
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2022 The Chromium Authors and Alex313031. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
CANVAS_DIMENSIONS, 40,
|
||||
PATH_COLOR_ARGB, 0xFF, 0xFB, 0xBC, 0x04,
|
||||
MOVE_TO, 20, 4,
|
||||
CUBIC_TO, 11.17f, 4, 4, 11.17f, 4, 20,
|
||||
R_CUBIC_TO, 0, 8.83f, 7.17f, 16, 16, 16,
|
||||
R_CUBIC_TO, 8.83f, 0, 16, -7.17f, 16, -16,
|
||||
CUBIC_TO_SHORTHAND, 28.83f, 4, 20, 4,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 1, 23,
|
||||
R_H_LINE_TO, -3,
|
||||
R_V_LINE_TO, -9,
|
||||
R_H_LINE_TO, 3,
|
||||
R_V_LINE_TO, 9,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 0, -12,
|
||||
R_H_LINE_TO, -3,
|
||||
R_V_LINE_TO, -3,
|
||||
R_H_LINE_TO, 3,
|
||||
R_V_LINE_TO, 3,
|
||||
CLOSE
|
||||
|
||||
CANVAS_DIMENSIONS, 20,
|
||||
PATH_COLOR_ARGB, 0xFF, 0xFB, 0xBC, 0x04,
|
||||
MOVE_TO, 10, 2,
|
||||
R_CUBIC_TO, -4.42f, 0, -8, 3.58f, -8, 8,
|
||||
R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8,
|
||||
R_CUBIC_TO, 4.42f, 0, 8, -3.58f, 8, -8,
|
||||
R_CUBIC_TO, 0, -4.42f, -3.58f, -8, -8, -8,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 1, 12,
|
||||
H_LINE_TO, 9,
|
||||
V_LINE_TO, 9,
|
||||
R_H_LINE_TO, 2,
|
||||
R_V_LINE_TO, 5,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 0, -6,
|
||||
H_LINE_TO, 9,
|
||||
V_LINE_TO, 6,
|
||||
R_H_LINE_TO, 2,
|
||||
R_V_LINE_TO, 2,
|
||||
CLOSE
|
30
src/ash/resources/vector_icons/unified_menu_info.icon
Normal file
30
src/ash/resources/vector_icons/unified_menu_info.icon
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2022 The Chromium Authors and Alex313031. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
CANVAS_DIMENSIONS, 20,
|
||||
PATH_COLOR_ARGB, 0xFF, 0xFB, 0xBC, 0x04,
|
||||
MOVE_TO, 10, 2,
|
||||
R_CUBIC_TO, 4.42f, 0, 8, 3.58f, 8, 8,
|
||||
R_CUBIC_TO, 0, 4.42f, -3.58f, 8, -8, 8,
|
||||
R_CUBIC_TO, -4.42f, 0, -8, -3.58f, -8, -8,
|
||||
R_CUBIC_TO, 0, -4.42f, 3.58f, -8, 8, -8,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 0, 14,
|
||||
R_CUBIC_TO, 3.31f, 0, 6, -2.69f, 6, -6,
|
||||
R_CUBIC_TO, 0, -3.31f, -2.69f, -6, -6, -6,
|
||||
R_CUBIC_TO, -3.31f, 0, -6, 2.69f, -6, 6,
|
||||
R_CUBIC_TO, 0, 3.31f, 2.69f, 6, 6, 6,
|
||||
CLOSE,
|
||||
R_MOVE_TO, -1, -2,
|
||||
R_V_LINE_TO, -4,
|
||||
R_H_LINE_TO, 2,
|
||||
R_V_LINE_TO, 4,
|
||||
H_LINE_TO, 9,
|
||||
CLOSE,
|
||||
R_MOVE_TO, 0, -6,
|
||||
V_LINE_TO, 6,
|
||||
R_H_LINE_TO, 2,
|
||||
R_V_LINE_TO, 2,
|
||||
H_LINE_TO, 9,
|
||||
CLOSE
|
173
src/base/win/shortcut.h
Normal file
173
src/base/win/shortcut.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
// Copyright (c) 2022 The Chromium Authors and Alex313031. 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_WIN_SHORTCUT_H_
|
||||
#define BASE_WIN_SHORTCUT_H_
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "base/base_export.h"
|
||||
#include "base/check.h"
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace base {
|
||||
namespace win {
|
||||
|
||||
enum class ShortcutOperation {
|
||||
// Create a new shortcut (overwriting if necessary).
|
||||
kCreateAlways = 0,
|
||||
// Overwrite an existing shortcut (fails if the shortcut doesn't exist).
|
||||
// If the arguments are not specified on the new shortcut, keep the old
|
||||
// shortcut's arguments.
|
||||
kReplaceExisting,
|
||||
// Update specified properties only on an existing shortcut.
|
||||
kUpdateExisting,
|
||||
};
|
||||
|
||||
// Properties for shortcuts. Properties set will be applied to the shortcut on
|
||||
// creation/update, others will be ignored.
|
||||
// Callers are encouraged to use the setters provided which take care of
|
||||
// setting |options| as desired.
|
||||
struct BASE_EXPORT ShortcutProperties {
|
||||
using IndividualProperties = uint32_t;
|
||||
static constexpr IndividualProperties PROPERTIES_TARGET = 1U << 0;
|
||||
static constexpr IndividualProperties PROPERTIES_WORKING_DIR = 1U << 1;
|
||||
static constexpr IndividualProperties PROPERTIES_ARGUMENTS = 1U << 2;
|
||||
static constexpr IndividualProperties PROPERTIES_DESCRIPTION = 1U << 3;
|
||||
static constexpr IndividualProperties PROPERTIES_ICON = 1U << 4;
|
||||
static constexpr IndividualProperties PROPERTIES_APP_ID = 1U << 5;
|
||||
static constexpr IndividualProperties PROPERTIES_DUAL_MODE = 1U << 6;
|
||||
static constexpr IndividualProperties PROPERTIES_TOAST_ACTIVATOR_CLSID = 1U
|
||||
<< 7;
|
||||
// Be sure to update the values below when adding a new property.
|
||||
static constexpr IndividualProperties PROPERTIES_ALL =
|
||||
PROPERTIES_TARGET | PROPERTIES_WORKING_DIR | PROPERTIES_ARGUMENTS |
|
||||
PROPERTIES_DESCRIPTION | PROPERTIES_ICON | PROPERTIES_APP_ID |
|
||||
PROPERTIES_DUAL_MODE | PROPERTIES_TOAST_ACTIVATOR_CLSID;
|
||||
|
||||
ShortcutProperties();
|
||||
ShortcutProperties(const ShortcutProperties& other);
|
||||
~ShortcutProperties();
|
||||
|
||||
void set_target(const FilePath& target_in) {
|
||||
target = target_in;
|
||||
options |= PROPERTIES_TARGET;
|
||||
}
|
||||
|
||||
void set_working_dir(const FilePath& working_dir_in) {
|
||||
working_dir = working_dir_in;
|
||||
options |= PROPERTIES_WORKING_DIR;
|
||||
}
|
||||
|
||||
void set_arguments(const std::wstring& arguments_in) {
|
||||
arguments = arguments_in;
|
||||
options |= PROPERTIES_ARGUMENTS;
|
||||
}
|
||||
|
||||
void set_description(const std::wstring& description_in);
|
||||
|
||||
void set_icon(const FilePath& icon_in, int icon_index_in) {
|
||||
icon = icon_in;
|
||||
icon_index = icon_index_in;
|
||||
options |= PROPERTIES_ICON;
|
||||
}
|
||||
|
||||
void set_app_id(const std::wstring& app_id_in) {
|
||||
app_id = app_id_in;
|
||||
options |= PROPERTIES_APP_ID;
|
||||
}
|
||||
|
||||
void set_dual_mode(bool dual_mode_in) {
|
||||
dual_mode = dual_mode_in;
|
||||
options |= PROPERTIES_DUAL_MODE;
|
||||
}
|
||||
|
||||
void set_toast_activator_clsid(const CLSID& toast_activator_clsid_in) {
|
||||
toast_activator_clsid = toast_activator_clsid_in;
|
||||
options |= PROPERTIES_TOAST_ACTIVATOR_CLSID;
|
||||
}
|
||||
|
||||
// The target to launch from this shortcut. This is mandatory when creating
|
||||
// a shortcut.
|
||||
FilePath target;
|
||||
// The name of the working directory when launching the shortcut.
|
||||
FilePath working_dir;
|
||||
// The arguments to be applied to |target| when launching from this shortcut.
|
||||
std::wstring arguments = (L"--autoplay-policy=user-gesture-required");
|
||||
// The localized description of the shortcut.
|
||||
// The length of this string must be no larger than INFOTIPSIZE.
|
||||
std::wstring description;
|
||||
// The path to the icon (can be a dll or exe, in which case |icon_index| is
|
||||
// the resource id).
|
||||
FilePath icon;
|
||||
int icon_index = -1;
|
||||
// The app model id for the shortcut.
|
||||
std::wstring app_id;
|
||||
// Whether this is a dual mode shortcut (Win8+).
|
||||
bool dual_mode = false;
|
||||
// The CLSID of the COM object registered with the OS via the shortcut. This
|
||||
// is for app activation via user interaction with a toast notification in the
|
||||
// Action Center. (Win10 version 1607, build 14393, and beyond).
|
||||
CLSID toast_activator_clsid;
|
||||
// Bitfield made of IndividualProperties. Properties set in |options| will be
|
||||
// set on the shortcut, others will be ignored.
|
||||
uint32_t options = 0U;
|
||||
};
|
||||
|
||||
// This method creates (or updates) a shortcut link at `shortcut_path` using the
|
||||
// information given through `properties`.
|
||||
// Ensure you have initialized COM before calling into this function.
|
||||
// `operation`: a choice from the ShortcutOperation enum.
|
||||
// If `operation` is kReplaceExisting or kUpdateExisting and
|
||||
// `shortcut_path` does not exist, this method is a no-op and returns false.
|
||||
BASE_EXPORT bool CreateOrUpdateShortcutLink(
|
||||
const FilePath& shortcut_path,
|
||||
const ShortcutProperties& properties,
|
||||
ShortcutOperation operation);
|
||||
|
||||
// Resolves Windows shortcut (.LNK file).
|
||||
// This methods tries to resolve selected properties of a shortcut .LNK file.
|
||||
// The path of the shortcut to resolve is in |shortcut_path|. |options| is a bit
|
||||
// field composed of ShortcutProperties::IndividualProperties, to specify which
|
||||
// properties to read. It should be non-0. The resulting data are read into
|
||||
// |properties|, which must not be NULL. Note: PROPERTIES_TARGET will retrieve
|
||||
// the target path as stored in the shortcut but won't attempt to resolve that
|
||||
// path so it may not be valid. The function returns true if all requested
|
||||
// properties are successfully read. Otherwise some reads have failed and
|
||||
// intermediate values written to |properties| should be ignored.
|
||||
BASE_EXPORT bool ResolveShortcutProperties(const FilePath& shortcut_path,
|
||||
uint32_t options,
|
||||
ShortcutProperties* properties);
|
||||
|
||||
// Resolves Windows shortcut (.LNK file).
|
||||
// This is a wrapper to ResolveShortcutProperties() to handle the common use
|
||||
// case of resolving target and arguments. |target_path| and |args| are
|
||||
// optional output variables that are ignored if NULL (but at least one must be
|
||||
// non-NULL). The function returns true if all requested fields are found
|
||||
// successfully. Callers can safely use the same variable for both
|
||||
// |shortcut_path| and |target_path|.
|
||||
BASE_EXPORT bool ResolveShortcut(const FilePath& shortcut_path,
|
||||
FilePath* target_path,
|
||||
std::wstring* args);
|
||||
|
||||
// Pin to taskbar is only supported on Windows 7 and Windows 8. Returns true on
|
||||
// those platforms.
|
||||
BASE_EXPORT bool CanPinShortcutToTaskbar();
|
||||
|
||||
// Pins a shortcut to the taskbar on Windows 7 and 8. The |shortcut| file must
|
||||
// already exist and be a shortcut that points to an executable. The app id of
|
||||
// the shortcut is used to group windows and must be set correctly.
|
||||
BASE_EXPORT bool PinShortcutToTaskbar(const FilePath& shortcut);
|
||||
|
||||
// Unpins a shortcut from the Windows 7+ taskbar. The |shortcut| must exist and
|
||||
// already be pinned to the taskbar. The app id of the shortcut is used as the
|
||||
// identifier for the taskbar item to remove and must be set correctly.
|
||||
BASE_EXPORT bool UnpinShortcutFromTaskbar(const FilePath& shortcut);
|
||||
|
||||
} // namespace win
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_WIN_SHORTCUT_H_
|
148
src/build/config/arm.gni
Normal file
148
src/build/config/arm.gni
Normal file
|
@ -0,0 +1,148 @@
|
|||
# Copyright 2022 The Chromium Authors and Alex313031. 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/v8_target_cpu.gni")
|
||||
|
||||
# These are primarily relevant in current_cpu == "arm" contexts, where
|
||||
# ARM code is being compiled. But they can also be relevant in the
|
||||
# other contexts when the code will change its behavior based on the
|
||||
# cpu it wants to generate code for.
|
||||
if (current_cpu == "arm" || v8_current_cpu == "arm") {
|
||||
declare_args() {
|
||||
# Version of the ARM processor when compiling on ARM. Ignored on non-ARM
|
||||
# platforms.
|
||||
arm_version = 8
|
||||
|
||||
# The ARM architecture. This will be a string like "armv6" or "armv7-a".
|
||||
# An empty string means to use the default for the arm_version.
|
||||
arm_arch = "armv8.5-a"
|
||||
|
||||
# The ARM floating point hardware. This will be a string like "neon" or
|
||||
# "vfpv3". An empty string means to use the default for the arm_version.
|
||||
arm_fpu = ""
|
||||
|
||||
# The ARM variant-specific tuning mode. This will be a string like "armv6"
|
||||
# or "cortex-a15". An empty string means to use the default for the
|
||||
# arm_version.
|
||||
arm_tune = "armv8.5-a"
|
||||
|
||||
# Whether to use the neon FPU instruction set or not.
|
||||
arm_use_neon = "true"
|
||||
|
||||
# Whether to enable optional NEON code paths.
|
||||
arm_optionally_use_neon = true
|
||||
|
||||
# Thumb is a reduced instruction set available on some ARM processors that
|
||||
# has increased code density.
|
||||
arm_use_thumb = true
|
||||
}
|
||||
|
||||
if (current_os == "android" || target_os == "android") {
|
||||
arm_float_abi = "softfp"
|
||||
} else {
|
||||
declare_args() {
|
||||
# The ARM floating point mode. This is either the string "hard", "soft",
|
||||
# or "softfp". An empty string means to use the default one for the
|
||||
# arm_version.
|
||||
arm_float_abi = ""
|
||||
}
|
||||
}
|
||||
assert(arm_float_abi == "" || arm_float_abi == "hard" ||
|
||||
arm_float_abi == "soft" || arm_float_abi == "softfp")
|
||||
|
||||
if (arm_use_neon == "") {
|
||||
if (current_os == "linux" && target_cpu != v8_target_cpu) {
|
||||
# Don't use neon on V8 simulator builds as a default.
|
||||
arm_use_neon = false
|
||||
} else {
|
||||
arm_use_neon = true
|
||||
}
|
||||
}
|
||||
|
||||
if (arm_version == 6) {
|
||||
if (arm_arch == "") {
|
||||
# v8 can still with version 6 but only with the armv6k extension.
|
||||
arm_arch = "armv6k"
|
||||
}
|
||||
if (arm_tune != "") {
|
||||
arm_tune = ""
|
||||
}
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "softfp"
|
||||
}
|
||||
if (arm_fpu == "") {
|
||||
arm_fpu = "vfp"
|
||||
}
|
||||
arm_use_thumb = false
|
||||
arm_use_neon = false
|
||||
} else if (arm_version == 7) {
|
||||
if (arm_arch == "") {
|
||||
arm_arch = "armv7-a"
|
||||
}
|
||||
if (arm_tune == "") {
|
||||
arm_tune = "generic-armv7-a"
|
||||
}
|
||||
|
||||
if (arm_float_abi == "") {
|
||||
if (current_os == "linux" && target_cpu != v8_target_cpu) {
|
||||
# Default to the same as Android for V8 simulator builds.
|
||||
arm_float_abi = "softfp"
|
||||
} else {
|
||||
arm_float_abi = "hard"
|
||||
}
|
||||
}
|
||||
|
||||
if (arm_fpu == "") {
|
||||
if (arm_use_neon) {
|
||||
arm_fpu = "neon"
|
||||
} else {
|
||||
arm_fpu = "vfpv3-d16"
|
||||
}
|
||||
}
|
||||
} else if (arm_version == 8) {
|
||||
if (arm_arch == "") {
|
||||
arm_arch = "armv8-a"
|
||||
}
|
||||
if (arm_tune == "") {
|
||||
arm_tune = "generic-armv8-a"
|
||||
}
|
||||
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "hard"
|
||||
}
|
||||
|
||||
if (arm_fpu == "") {
|
||||
if (arm_use_neon) {
|
||||
arm_fpu = "neon"
|
||||
} else {
|
||||
arm_fpu = "vfpv3-d16"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (current_cpu == "arm64" || v8_current_cpu == "arm64") {
|
||||
# arm64 supports only "hard".
|
||||
arm_float_abi = "hard"
|
||||
arm_use_neon = true
|
||||
declare_args() {
|
||||
# Enables the new Armv8 branch protection features. Valid strings are:
|
||||
# - "pac": Enables Pointer Authentication Code (PAC, featured in Armv8.3)
|
||||
# - "standard": Enables both PAC and Branch Target Identification (Armv8.5).
|
||||
# - "none": No branch protection.
|
||||
arm_control_flow_integrity = "standard"
|
||||
|
||||
# TODO(cavalcantii): enable the feature for the following OSes next.
|
||||
if (is_mac || is_chromeos || is_fuchsia || is_win ||
|
||||
target_cpu != "arm64") {
|
||||
# target_cpu != "arm64" covers some cases (e.g. the ChromeOS x64 MSAN
|
||||
# build) where the target platform is x64, but V8 is configured to use
|
||||
# the arm64 simulator. Pointer authentication doesn't work properly
|
||||
# in this mode (yet).
|
||||
arm_control_flow_integrity = "none"
|
||||
}
|
||||
}
|
||||
assert(arm_control_flow_integrity == "none" ||
|
||||
arm_control_flow_integrity == "standard" ||
|
||||
arm_control_flow_integrity == "pac",
|
||||
"Invalid branch protection option")
|
||||
}
|
2705
src/build/config/compiler/BUILD.gn
Normal file
2705
src/build/config/compiler/BUILD.gn
Normal file
File diff suppressed because it is too large
Load diff
157
src/build/config/mac/BUILD.gn
Normal file
157
src/build/config/mac/BUILD.gn
Normal file
|
@ -0,0 +1,157 @@
|
|||
# Copyright (c) 2022 The Chromium Authors and Alex313031. 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/apple/symbols.gni")
|
||||
import("//build/config/c++/c++.gni")
|
||||
import("//build/config/mac/mac_sdk.gni")
|
||||
import("//build/config/sysroot.gni")
|
||||
import("//build/toolchain/goma.gni")
|
||||
import("//build/toolchain/rbe.gni")
|
||||
|
||||
# This is included by reference in the //build/config/compiler config that
|
||||
# is applied to all targets. It is here to separate out the logic.
|
||||
config("compiler") {
|
||||
# These flags are shared between the C compiler and linker.
|
||||
common_mac_flags = []
|
||||
|
||||
# CPU architecture.
|
||||
if (current_cpu == "x64") {
|
||||
clang_arch = "x86_64"
|
||||
} else if (current_cpu == "x86") {
|
||||
clang_arch = "i386"
|
||||
} else if (current_cpu == "arm64") {
|
||||
clang_arch = current_cpu
|
||||
} else {
|
||||
assert(false, "unknown current_cpu $current_cpu")
|
||||
}
|
||||
if (host_os == "mac") {
|
||||
common_mac_flags += [
|
||||
"-arch",
|
||||
clang_arch,
|
||||
]
|
||||
} else {
|
||||
common_mac_flags += [ "--target=$clang_arch-apple-macos" ]
|
||||
}
|
||||
|
||||
# This is here so that all files get recompiled after an Xcode update.
|
||||
# (defines are passed via the command line, and build system rebuild things
|
||||
# when their commandline changes). Nothing should ever read this define.
|
||||
defines = [ "CR_XCODE_VERSION=$xcode_version" ]
|
||||
|
||||
asmflags = [ "-O3", ] + common_mac_flags
|
||||
cflags = [ "-O3", ] + common_mac_flags
|
||||
|
||||
# Without this, the constructors and destructors of a C++ object inside
|
||||
# an Objective C struct won't be called, which is very bad.
|
||||
cflags_objcc = [ "-fobjc-call-cxx-cdtors" ]
|
||||
|
||||
ldflags = [ "-Wl,-O3", ] + common_mac_flags
|
||||
|
||||
if (target_cpu == "x64") {
|
||||
cflags += [ "-maes", "-mavx", "-mavx2", "-ffp-contract=fast", "-mf16c", "-mfma", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
|
||||
if (current_cpu == "x64") {
|
||||
cflags += [ "-maes", "-mavx", "-mavx2", "-ffp-contract=fast", "-mf16c", "-mfma", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
|
||||
if (save_unstripped_output) {
|
||||
ldflags += [ "-Wcrl,unstripped," + rebase_path(root_out_dir) ]
|
||||
}
|
||||
|
||||
if (export_libcxxabi_from_executables) {
|
||||
ldflags += [ "-Wl,-undefined,dynamic_lookup" ]
|
||||
}
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler:runtime_library
|
||||
# config that is applied to all targets. It is here to separate out the logic
|
||||
# that is Mac-only. Please see that target for advice on what should go in
|
||||
# :runtime_library vs. :compiler.
|
||||
config("runtime_library") {
|
||||
common_flags = [
|
||||
"-isysroot",
|
||||
rebase_path(sysroot, root_build_dir),
|
||||
"-mmacos-version-min=$mac_deployment_target",
|
||||
]
|
||||
|
||||
asmflags = common_flags
|
||||
cflags = common_flags
|
||||
ldflags = common_flags
|
||||
|
||||
# Prevent Mac OS X AssertMacros.h (included by system header) from defining
|
||||
# macros that collide with common names, like 'check', 'require', and
|
||||
# 'verify'.
|
||||
# http://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/AssertMacros.h
|
||||
defines = [ "__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0" ]
|
||||
}
|
||||
|
||||
# On Mac, this is used for everything except static libraries.
|
||||
config("mac_dynamic_flags") {
|
||||
ldflags = [ "-Wl,-ObjC", "-Wl,-O3", ] # Always load Objective-C categories and classes.
|
||||
|
||||
if (is_component_build) {
|
||||
ldflags += [
|
||||
# Path for loading shared libraries for unbundled binaries.
|
||||
"-Wl,-rpath,@loader_path/.",
|
||||
|
||||
# Path for loading shared libraries for bundled binaries. Get back from
|
||||
# Binary.app/Contents/MacOS.
|
||||
"-Wl,-rpath,@loader_path/../../..",
|
||||
]
|
||||
|
||||
# Path for loading shared libraries for unbundled binaries for
|
||||
# the host toolchain (see https://crbug.com/1315433). Only used
|
||||
# for when building for iOS.
|
||||
if (target_os == "ios" && current_toolchain == host_toolchain) {
|
||||
ldflags += [
|
||||
"-Wl,-rpath,@loader_path/" +
|
||||
rebase_path(get_label_info(":mac_dynamic_flags", "root_out_dir"),
|
||||
root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# The ldflags referenced below are handled by
|
||||
# //build/toolchain/apple/linker_driver.py.
|
||||
# Remove this config if a target wishes to change the arguments passed to the
|
||||
# strip command during linking. This config by default strips all symbols
|
||||
# from a binary, but some targets may wish to specify an exports file to
|
||||
# preserve specific symbols.
|
||||
config("strip_all") {
|
||||
if (enable_stripping) {
|
||||
ldflags = [ "-Wcrl,strip,-x,-S", "-Wl,-O3", ]
|
||||
}
|
||||
}
|
||||
|
||||
# When building with Goma, all inputs must be relative to the build directory.
|
||||
# If using the system Xcode, which typically resides outside the build root, a
|
||||
# symlink to the SDK is created in the build directory, and the path to that
|
||||
# link is stored in $mac_sdk_path. If an action references a file in the SDK as
|
||||
# an input, GN will complain that no target generates the file because it is
|
||||
# below the $root_build_dir. The below action lists as outputs the files in the
|
||||
# SDK that are referenced as inputs to actions, so that GN thinks a target has
|
||||
# generated them. The list is centralized here, as multiple targets need to
|
||||
# reference the same files, and an output can only be generated once.
|
||||
#
|
||||
# The symbolic link for $mac_sdk_path is set up by
|
||||
# //build/config/apple/sdk_info.py in //build/config/mac/mac_sdk.gni.
|
||||
if (use_system_xcode && (use_goma || use_remoteexec) && target_os == "mac" &&
|
||||
current_toolchain == default_toolchain) {
|
||||
action("sdk_inputs") {
|
||||
script = "//build/noop.py"
|
||||
outputs = [
|
||||
"$mac_sdk_path/usr/include/mach/exc.defs",
|
||||
"$mac_sdk_path/usr/include/mach/mach_exc.defs",
|
||||
"$mac_sdk_path/usr/include/mach/notify.defs",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("sdk_inputs") {
|
||||
if (current_toolchain != default_toolchain) {
|
||||
public_deps = [ ":sdk_inputs($default_toolchain)" ]
|
||||
}
|
||||
}
|
||||
}
|
614
src/build/config/win/BUILD.gn
Normal file
614
src/build/config/win/BUILD.gn
Normal file
|
@ -0,0 +1,614 @@
|
|||
# Copyright (c) 2022 The Chromium Authors and Alex313031. 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/c++/c++.gni")
|
||||
import("//build/config/chrome_build.gni")
|
||||
import("//build/config/clang/clang.gni")
|
||||
import("//build/config/compiler/compiler.gni")
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/config/win/control_flow_guard.gni")
|
||||
import("//build/config/win/visual_studio_version.gni")
|
||||
import("//build/timestamp.gni")
|
||||
import("//build/toolchain/goma.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
assert(is_win)
|
||||
|
||||
declare_args() {
|
||||
# Turn this on to have the linker output extra timing information.
|
||||
win_linker_timing = false
|
||||
|
||||
# possible values for target_winuwp_version:
|
||||
# "10" - Windows UWP 10
|
||||
# "8.1" - Windows RT 8.1
|
||||
# "8.0" - Windows RT 8.0
|
||||
target_winuwp_version = "10"
|
||||
|
||||
# possible values:
|
||||
# "app" - Windows Store Applications
|
||||
# "phone" - Windows Phone Applications
|
||||
# "system" - Windows Drivers and Tools
|
||||
# "server" - Windows Server Applications
|
||||
# "desktop" - Windows Desktop Applications
|
||||
target_winuwp_family = "app"
|
||||
|
||||
# Set this to use clang-style diagnostics format instead of MSVC-style, which
|
||||
# is useful in e.g. Emacs compilation mode.
|
||||
# E.g.:
|
||||
# Without this, clang emits a diagnostic message like this:
|
||||
# foo/bar.cc(12,34): error: something went wrong
|
||||
# and with this switch, clang emits it like this:
|
||||
# foo/bar.cc:12:34: error: something went wrong
|
||||
use_clang_diagnostics_format = false
|
||||
|
||||
# Indicates whether to use /pdbpagesize:8192 to allow PDBs larger than 4 GiB.
|
||||
# This requires updated debugging and profiling tools which are not widely
|
||||
# distributed yet which is why it is currently opt-in.
|
||||
use_large_pdbs = false
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler config that
|
||||
# is applied to all targets. It is here to separate out the logic that is
|
||||
# Windows-only.
|
||||
config("compiler") {
|
||||
if (current_cpu == "x86") {
|
||||
asmflags = [
|
||||
# When /safeseh is specified, the linker will only produce an image if it
|
||||
# can also produce a table of the image's safe exception handlers. This
|
||||
# table specifies for the operating system which exception handlers are
|
||||
# valid for the image. Note that /SAFESEH isn't accepted on the command
|
||||
# line, only /safeseh. This is only accepted by ml.exe, not ml64.exe.
|
||||
"/safeseh",
|
||||
]
|
||||
}
|
||||
|
||||
cflags = [
|
||||
"/Gy", # Enable function-level linking.
|
||||
"/FS", # Preserve previous PDB behavior.
|
||||
"/bigobj", # Some of our files are bigger than the regular limits.
|
||||
"/utf-8", # Assume UTF-8 by default to avoid code page dependencies.
|
||||
]
|
||||
|
||||
if (is_clang) {
|
||||
cflags += [
|
||||
"/Zc:twoPhase",
|
||||
|
||||
# Consistently use backslash as the path separator when expanding the
|
||||
# __FILE__ macro when targeting Windows regardless of the build
|
||||
# environment.
|
||||
"-ffile-reproducible",
|
||||
]
|
||||
}
|
||||
|
||||
# Force C/C++ mode for the given GN detected file type. This is necessary
|
||||
# for precompiled headers where the same source file is compiled in both
|
||||
# modes.
|
||||
cflags_c = [ "/TC" ]
|
||||
cflags_cc = [ "/TP" ]
|
||||
|
||||
cflags += [
|
||||
# Work around crbug.com/526851, bug in VS 2015 RTM compiler.
|
||||
"/Zc:sizedDealloc-",
|
||||
]
|
||||
|
||||
if (is_clang) {
|
||||
# Required to make the 19041 SDK compatible with clang-cl.
|
||||
# See https://crbug.com/1089996 issue #2 for details.
|
||||
cflags += [ "/D__WRL_ENABLE_FUNCTION_STATICS__" ]
|
||||
|
||||
# Tell clang which version of MSVC to emulate.
|
||||
cflags += [ "-fmsc-version=1916" ]
|
||||
|
||||
if (is_component_build) {
|
||||
cflags += [
|
||||
# Do not export inline member functions. This makes component builds
|
||||
# faster. This is similar to -fvisibility-inlines-hidden.
|
||||
"/Zc:dllexportInlines-",
|
||||
]
|
||||
}
|
||||
|
||||
if (current_cpu == "x86") {
|
||||
if (host_cpu == "x86" || host_cpu == "x64") {
|
||||
cflags += [ "-m32" ]
|
||||
} else {
|
||||
cflags += [ "--target=i386-windows", "/O3", "/clang:-O3", "-Xclang", "-O3", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
} else if (current_cpu == "x64") {
|
||||
if (host_cpu == "x86" || host_cpu == "x64") {
|
||||
cflags += [ "-m64" ]
|
||||
} else {
|
||||
cflags += [ "--target=x86_64-windows" ]
|
||||
}
|
||||
} else if (current_cpu == "arm64") {
|
||||
cflags += [ "--target=arm64-windows", "/O3", "/clang:-O3", "-Xclang", "-O3", "-Wno-unused-command-line-argument", ]
|
||||
} else {
|
||||
assert(false, "unknown current_cpu " + current_cpu)
|
||||
}
|
||||
|
||||
# Chrome currently requires SSE3. Clang supports targeting any Intel
|
||||
# microarchitecture. MSVC only supports a subset of architectures, and the
|
||||
# next step after SSE2 will be AVX.
|
||||
# "/fp:fast", enables FMA.
|
||||
if (current_cpu == "x86" || current_cpu == "x64") {
|
||||
cflags += [
|
||||
"/O3",
|
||||
"-mavx",
|
||||
"-maes",
|
||||
"/clang:-O3",
|
||||
"/clang:-mavx",
|
||||
"/clang:-maes",
|
||||
"-Xclang", "-O3",
|
||||
"-Wno-unused-command-line-argument",
|
||||
]
|
||||
}
|
||||
|
||||
if (exec_script("//build/win/use_ansi_codes.py", [], "trim string") ==
|
||||
"True") {
|
||||
cflags += [
|
||||
# cmd.exe doesn't understand ANSI escape codes by default,
|
||||
# so only enable them if something emulating them is around.
|
||||
"-fansi-escape-codes",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_clang_diagnostics_format) {
|
||||
cflags += [ "/clang:-fdiagnostics-format=clang" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Disabled with cc_wrapper because of https://github.com/mozilla/sccache/issues/264
|
||||
if (use_lld && !use_thin_lto && (is_clang || !use_goma) && cc_wrapper == "") {
|
||||
# /Brepro lets the compiler not write the mtime field in the .obj output.
|
||||
# link.exe /incremental relies on this field to work correctly, but lld
|
||||
# never looks at this timestamp, so it's safe to pass this flag with
|
||||
# lld and get more deterministic compiler output in return.
|
||||
# In LTO builds, the compiler doesn't write .obj files containing mtimes,
|
||||
# so /Brepro is ignored there.
|
||||
cflags += [ "/Brepro" ]
|
||||
}
|
||||
|
||||
ldflags = []
|
||||
|
||||
if (use_lld) {
|
||||
# lld defaults to writing the current time in the pe/coff header.
|
||||
# For build reproducibility, pass an explicit timestamp. See
|
||||
# build/compute_build_timestamp.py for how the timestamp is chosen.
|
||||
# (link.exe also writes the current time, but it doesn't have a flag to
|
||||
# override that behavior.)
|
||||
ldflags += [ "/TIMESTAMP:" + build_timestamp ]
|
||||
|
||||
# Don't look for libpaths in %LIB%, similar to /X in cflags above.
|
||||
ldflags += [ "/lldignoreenv" ]
|
||||
ldflags += [ "/opt:lldlto=3", ]
|
||||
}
|
||||
|
||||
if (use_large_pdbs) {
|
||||
# This allows PDBs up to 8 GiB in size. This requires lld-link.exe or
|
||||
# link.exe from VS 2022 or later.
|
||||
ldflags += [ "/pdbpagesize:8192" ]
|
||||
}
|
||||
|
||||
if (!is_debug && !is_component_build) {
|
||||
# Enable standard linker optimizations like GC (/OPT:REF) and ICF in static
|
||||
# release builds.
|
||||
# Release builds always want these optimizations, so enable them explicitly.
|
||||
ldflags += [
|
||||
"/OPT:REF",
|
||||
"/OPT:ICF",
|
||||
"/INCREMENTAL:NO",
|
||||
"/FIXED:NO",
|
||||
"/OPT:lldlto=3",
|
||||
"-mllvm:-march=sandybridge",
|
||||
]
|
||||
|
||||
if (use_lld) {
|
||||
# String tail merging leads to smaller binaries, but they don't compress
|
||||
# as well, leading to increased mini_installer size (crbug.com/838449).
|
||||
ldflags += [ "/OPT:NOLLDTAILMERGE" ]
|
||||
}
|
||||
|
||||
# TODO(siggi): Is this of any use anymore?
|
||||
# /PROFILE ensures that the PDB file contains FIXUP information (growing the
|
||||
# PDB file by about 5%) but does not otherwise alter the output binary. It
|
||||
# is enabled opportunistically for builds where it is not prohibited (not
|
||||
# supported when incrementally linking, or using /debug:fastlink).
|
||||
ldflags += [ "/PROFILE" ]
|
||||
}
|
||||
|
||||
# arflags apply only to static_libraries. The normal linker configs are only
|
||||
# set for executable and shared library targets so arflags must be set
|
||||
# elsewhere. Since this is relatively contained, we just apply them in this
|
||||
# more general config and they will only have an effect on static libraries.
|
||||
arflags = [
|
||||
# "No public symbols found; archive member will be inaccessible." This
|
||||
# means that one or more object files in the library can never be
|
||||
# pulled in to targets that link to this library. It's just a warning that
|
||||
# the source file is a no-op.
|
||||
"/ignore:4221",
|
||||
]
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler:runtime_library
|
||||
# config that is applied to all targets. It is here to separate out the logic
|
||||
# that is Windows-only. Please see that target for advice on what should go in
|
||||
# :runtime_library vs. :compiler.
|
||||
config("runtime_library") {
|
||||
cflags = []
|
||||
cflags_cc = []
|
||||
|
||||
# Defines that set up the CRT.
|
||||
defines = [
|
||||
"__STD_C",
|
||||
"_CRT_RAND_S",
|
||||
"_CRT_SECURE_NO_DEPRECATE",
|
||||
"_SCL_SECURE_NO_DEPRECATE",
|
||||
]
|
||||
|
||||
# Defines that set up the Windows SDK.
|
||||
defines += [
|
||||
"_ATL_NO_OPENGL",
|
||||
"_WINDOWS",
|
||||
"CERT_CHAIN_PARA_HAS_EXTRA_FIELDS",
|
||||
"PSAPI_VERSION=2",
|
||||
"WIN32",
|
||||
"_SECURE_ATL",
|
||||
]
|
||||
|
||||
if (current_os == "winuwp") {
|
||||
# When targeting Windows Runtime, certain compiler/linker flags are
|
||||
# necessary.
|
||||
defines += [
|
||||
"WINUWP",
|
||||
"__WRL_NO_DEFAULT_LIB__",
|
||||
]
|
||||
if (target_winuwp_family == "app") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PC_APP" ]
|
||||
} else if (target_winuwp_family == "phone") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" ]
|
||||
} else if (target_winuwp_family == "system") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SYSTEM" ]
|
||||
} else if (target_winuwp_family == "server") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SERVER" ]
|
||||
} else {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ]
|
||||
}
|
||||
cflags_cc += [ "/EHsc" ]
|
||||
|
||||
# This warning is given because the linker cannot tell the difference
|
||||
# between consuming WinRT APIs versus authoring WinRT within static
|
||||
# libraries as such this warning is always given by the linker. Since
|
||||
# consuming WinRT APIs within a library is legitimate but authoring
|
||||
# WinRT APis is not allowed, this warning is disabled to ignore the
|
||||
# legitimate consumption of WinRT APIs within static library builds.
|
||||
arflags = [ "/IGNORE:4264" ]
|
||||
|
||||
if (target_winuwp_version == "10") {
|
||||
defines += [ "WIN10=_WIN32_WINNT_WIN10" ]
|
||||
} else if (target_winuwp_version == "8.1") {
|
||||
defines += [ "WIN8_1=_WIN32_WINNT_WINBLUE" ]
|
||||
} else if (target_winuwp_version == "8.0") {
|
||||
defines += [ "WIN8=_WIN32_WINNT_WIN8" ]
|
||||
}
|
||||
} else {
|
||||
# When not targeting Windows Runtime, make sure the WINAPI family is set
|
||||
# to desktop.
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Chromium supports running on Windows 7, but if these constants are set to
|
||||
# Windows 7, then newer APIs aren't made available by the Windows SDK.
|
||||
# So we set this to Windows 10 and then are careful to check at runtime
|
||||
# to only call newer APIs when they're available.
|
||||
# Some third-party libraries assume that these defines set what version of
|
||||
# Windows is available at runtime. Targets using these libraries need to
|
||||
# manually override this config for their compiles.
|
||||
config("winver") {
|
||||
defines = [
|
||||
"NTDDI_VERSION=NTDDI_WIN10_FE",
|
||||
|
||||
# We can't say `=_WIN32_WINNT_WIN10` here because some files do
|
||||
# `#if WINVER < 0x0600` without including windows.h before,
|
||||
# and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00.
|
||||
"_WIN32_WINNT=0x0A00",
|
||||
"WINVER=0x0A00",
|
||||
]
|
||||
}
|
||||
|
||||
# Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs.
|
||||
config("sdk_link") {
|
||||
if (current_cpu == "x86") {
|
||||
ldflags = [
|
||||
"/SAFESEH", # Not compatible with x64 so use only for x86.
|
||||
"/largeaddressaware",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This default linker setup is provided separately from the SDK setup so
|
||||
# targets who want different library configurations can remove this and specify
|
||||
# their own.
|
||||
config("common_linker_setup") {
|
||||
ldflags = [
|
||||
"/FIXED:NO",
|
||||
"/ignore:4199",
|
||||
"/ignore:4221",
|
||||
"/NXCOMPAT",
|
||||
"/DYNAMICBASE",
|
||||
]
|
||||
|
||||
if (win_linker_timing) {
|
||||
ldflags += [
|
||||
"/time",
|
||||
"/verbose:incr",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("default_cfg_compiler") {
|
||||
# Emit table of address-taken functions for Control-Flow Guard (CFG).
|
||||
# This is needed to allow functions to be called by code that is built
|
||||
# with CFG enabled, such as system libraries.
|
||||
# The CFG guards are only emitted if |win_enable_cfg_guards| is enabled.
|
||||
if (is_clang) {
|
||||
if (win_enable_cfg_guards) {
|
||||
cflags = [ "/guard:cf" ]
|
||||
} else {
|
||||
cflags = [ "/guard:cf,nochecks" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To disable CFG guards for a target, remove the "default_cfg_compiler"
|
||||
# config, and add "disable_guards_cfg_compiler" config.
|
||||
config("disable_guards_cfg_compiler") {
|
||||
# Emit table of address-taken functions for Control-Flow Guard (CFG).
|
||||
# This is needed to allow functions to be called by code that is built
|
||||
# with CFG enabled, such as system libraries.
|
||||
if (is_clang) {
|
||||
cflags = [ "/guard:cf,nochecks" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("cfi_linker") {
|
||||
# Control Flow Guard (CFG)
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/mt637065.aspx
|
||||
# /DYNAMICBASE (ASLR) is turned off in debug builds, therefore CFG cannot be
|
||||
# turned on either.
|
||||
# ASan and CFG leads to slow process startup. Chromium's test runner uses
|
||||
# lots of child processes, so this means things are really slow. Disable CFG
|
||||
# for now. https://crbug.com/846966
|
||||
if (!is_debug && !is_asan) {
|
||||
# Turn on CFG bitmap generation and CFG load config.
|
||||
ldflags = [ "/guard:cf" ]
|
||||
}
|
||||
}
|
||||
|
||||
# This is a superset of all the delayloads needed for chrome.exe, chrome.dll,
|
||||
# chrome_child.dll, and chrome_elf.dll. The linker will automatically ignore
|
||||
# anything which is not linked to the binary at all.
|
||||
# Most of the dlls are simply not required at startup (or at all, depending
|
||||
# on how the browser is used). The following dlls are interconnected and need to
|
||||
# be delayloaded together to ensure user32 does not load too early or at all,
|
||||
# depending on the process type: user32, gdi32, comctl32, comdlg32, cryptui,
|
||||
# d3d9, dwmapi, imm32, msi, ole32, oleacc, rstrtmgr, shell32, shlwapi, and
|
||||
# uxtheme.
|
||||
# There are some exceptions to this list which need to be declared separately.
|
||||
# Some dlls cannot be delayloaded by chrome_child.dll due to the sandbox
|
||||
# restrictions that prevent them from being loaded properly. Those dlls are
|
||||
# specified in the separate config below.
|
||||
# This config should also be used for any test binary whose goal is to run
|
||||
# tests with the full browser.
|
||||
config("delayloads") {
|
||||
ldflags = [
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
|
||||
"/DELAYLOAD:comctl32.dll",
|
||||
"/DELAYLOAD:comdlg32.dll",
|
||||
"/DELAYLOAD:credui.dll",
|
||||
"/DELAYLOAD:cryptui.dll",
|
||||
"/DELAYLOAD:d3d11.dll",
|
||||
"/DELAYLOAD:d3d9.dll",
|
||||
"/DELAYLOAD:dwmapi.dll",
|
||||
"/DELAYLOAD:dxgi.dll",
|
||||
"/DELAYLOAD:dxva2.dll",
|
||||
"/DELAYLOAD:esent.dll",
|
||||
"/DELAYLOAD:gdi32.dll",
|
||||
"/DELAYLOAD:hid.dll",
|
||||
"/DELAYLOAD:imagehlp.dll",
|
||||
"/DELAYLOAD:imm32.dll",
|
||||
"/DELAYLOAD:msi.dll",
|
||||
"/DELAYLOAD:netapi32.dll",
|
||||
"/DELAYLOAD:ncrypt.dll",
|
||||
"/DELAYLOAD:ole32.dll",
|
||||
"/DELAYLOAD:oleacc.dll",
|
||||
"/DELAYLOAD:propsys.dll",
|
||||
"/DELAYLOAD:psapi.dll",
|
||||
"/DELAYLOAD:rpcrt4.dll",
|
||||
"/DELAYLOAD:rstrtmgr.dll",
|
||||
"/DELAYLOAD:setupapi.dll",
|
||||
"/DELAYLOAD:shell32.dll",
|
||||
"/DELAYLOAD:shlwapi.dll",
|
||||
"/DELAYLOAD:urlmon.dll",
|
||||
"/DELAYLOAD:user32.dll",
|
||||
"/DELAYLOAD:usp10.dll",
|
||||
"/DELAYLOAD:uxtheme.dll",
|
||||
"/DELAYLOAD:wer.dll",
|
||||
"/DELAYLOAD:wevtapi.dll",
|
||||
"/DELAYLOAD:wininet.dll",
|
||||
"/DELAYLOAD:winusb.dll",
|
||||
"/DELAYLOAD:wsock32.dll",
|
||||
"/DELAYLOAD:wtsapi32.dll",
|
||||
]
|
||||
}
|
||||
|
||||
config("delayloads_not_for_child_dll") {
|
||||
ldflags = [
|
||||
"/DELAYLOAD:advapi32.dll",
|
||||
"/DELAYLOAD:crypt32.dll",
|
||||
"/DELAYLOAD:dbghelp.dll",
|
||||
"/DELAYLOAD:dhcpcsvc.dll",
|
||||
"/DELAYLOAD:dwrite.dll",
|
||||
"/DELAYLOAD:iphlpapi.dll",
|
||||
"/DELAYLOAD:oleaut32.dll",
|
||||
"/DELAYLOAD:secur32.dll",
|
||||
"/DELAYLOAD:uiautomationcore.dll",
|
||||
"/DELAYLOAD:userenv.dll",
|
||||
"/DELAYLOAD:winhttp.dll",
|
||||
"/DELAYLOAD:winmm.dll",
|
||||
"/DELAYLOAD:winspool.drv",
|
||||
"/DELAYLOAD:wintrust.dll",
|
||||
"/DELAYLOAD:ws2_32.dll",
|
||||
]
|
||||
}
|
||||
|
||||
# CRT --------------------------------------------------------------------------
|
||||
|
||||
# Configures how the runtime library (CRT) is going to be used.
|
||||
# See https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx for a reference of
|
||||
# what each value does.
|
||||
config("default_crt") {
|
||||
if (is_component_build) {
|
||||
# Component mode: dynamic CRT. Since the library is shared, it requires
|
||||
# exceptions or will give errors about things not matching, so keep
|
||||
# exceptions on.
|
||||
configs = [ ":dynamic_crt" ]
|
||||
} else {
|
||||
if (current_os == "winuwp") {
|
||||
# https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/
|
||||
# contains a details explanation of what is happening with the Windows
|
||||
# CRT in Visual Studio releases related to Windows store applications.
|
||||
configs = [ ":dynamic_crt" ]
|
||||
} else {
|
||||
# Desktop Windows: static CRT.
|
||||
configs = [ ":static_crt" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Use this to force use of the release CRT when building perf-critical build
|
||||
# tools that need to be fully optimized even in debug builds, for those times
|
||||
# when the debug CRT is part of the bottleneck. This also avoids *implicitly*
|
||||
# defining _DEBUG.
|
||||
config("release_crt") {
|
||||
if (is_component_build) {
|
||||
cflags = [ "/MD" ]
|
||||
|
||||
if (use_custom_libcxx) {
|
||||
# On Windows, including libcpmt[d]/msvcprt[d] explicitly links the C++
|
||||
# standard library, which libc++ needs for exception_ptr internals.
|
||||
ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MT" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config("dynamic_crt") {
|
||||
if (is_debug) {
|
||||
# This pulls in the DLL debug CRT and defines _DEBUG
|
||||
cflags = [ "/MDd" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:msvcprtd.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MD" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config("static_crt") {
|
||||
if (is_debug) {
|
||||
# This pulls in the static debug CRT and defines _DEBUG
|
||||
cflags = [ "/MTd" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmtd.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MT" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Subsystem --------------------------------------------------------------------
|
||||
|
||||
# This is appended to the subsystem to specify a minimum version.
|
||||
if (current_cpu == "x64") {
|
||||
# The number after the comma is the minimum required OS version.
|
||||
# 5.02 = Windows Server 2003.
|
||||
subsystem_version_suffix = ",5.02"
|
||||
} else if (current_cpu == "arm64") {
|
||||
# Windows ARM64 requires Windows 10.
|
||||
subsystem_version_suffix = ",10.0"
|
||||
} else {
|
||||
# 5.01 = Windows XP.
|
||||
subsystem_version_suffix = ",5.01"
|
||||
}
|
||||
|
||||
config("console") {
|
||||
ldflags = [ "/SUBSYSTEM:CONSOLE$subsystem_version_suffix" ]
|
||||
}
|
||||
config("windowed") {
|
||||
ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ]
|
||||
}
|
||||
|
||||
# Incremental linking ----------------------------------------------------------
|
||||
|
||||
# Applies incremental linking or not depending on the current configuration.
|
||||
config("default_incremental_linking") {
|
||||
# Enable incremental linking for debug builds and all component builds - any
|
||||
# builds where performance is not job one.
|
||||
# TODO(thakis): Always turn this on with lld, no reason not to.
|
||||
if (is_debug || is_component_build) {
|
||||
ldflags = [ "/INCREMENTAL" ]
|
||||
if (use_lld) {
|
||||
# lld doesn't use ilk files and doesn't really have an incremental link
|
||||
# mode; the only effect of the flag is that the .lib file timestamp isn't
|
||||
# updated if the .lib doesn't change.
|
||||
# TODO(thakis): Why pass /OPT:NOREF for lld, but not otherwise?
|
||||
# TODO(thakis): /INCREMENTAL is on by default in link.exe, but not in
|
||||
# lld.
|
||||
ldflags += [ "/OPT:NOREF" ]
|
||||
}
|
||||
} else {
|
||||
ldflags = [ "/INCREMENTAL:NO" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Character set ----------------------------------------------------------------
|
||||
|
||||
# Not including this config means "ansi" (8-bit system codepage).
|
||||
config("unicode") {
|
||||
defines = [
|
||||
"_UNICODE",
|
||||
"UNICODE",
|
||||
]
|
||||
}
|
||||
|
||||
# Lean and mean ----------------------------------------------------------------
|
||||
|
||||
# Some third party code might not compile with WIN32_LEAN_AND_MEAN so we have
|
||||
# to have a separate config for it. Remove this config from your target to
|
||||
# get the "bloaty and accommodating" version of windows.h.
|
||||
config("lean_and_mean") {
|
||||
defines = [ "WIN32_LEAN_AND_MEAN" ]
|
||||
}
|
||||
|
||||
# Nominmax --------------------------------------------------------------------
|
||||
|
||||
# Some third party code defines NOMINMAX before including windows.h, which
|
||||
# then causes warnings when it's been previously defined on the command line.
|
||||
# For such targets, this config can be removed.
|
||||
|
||||
config("nominmax") {
|
||||
defines = [ "NOMINMAX" ]
|
||||
}
|
585
src/build/vs_toolchain.py
Normal file
585
src/build/vs_toolchain.py
Normal file
|
@ -0,0 +1,585 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2022 The Chromium Authors and Alex313031 and gz83. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import pipes
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from gn_helpers import ToGNString
|
||||
|
||||
# VS 2019 16.61 with 10.0.20348.0 SDK, 10.0.19041 version of Debuggers
|
||||
# with ARM64 libraries and UWP support.
|
||||
# See go/chromium-msvc-toolchain for instructions about how to update the
|
||||
# toolchain.
|
||||
#
|
||||
# When updating the toolchain, consider the following areas impacted by the
|
||||
# toolchain version:
|
||||
#
|
||||
# * //base/win/windows_version.cc NTDDI preprocessor check
|
||||
# Triggers a compiler error if the available SDK is older than the minimum.
|
||||
# * //build/config/win/BUILD.gn NTDDI_VERSION value
|
||||
# Affects the availability of APIs in the toolchain headers.
|
||||
# * //docs/windows_build_instructions.md mentions of VS or Windows SDK.
|
||||
# Keeps the document consistent with the toolchain version.
|
||||
TOOLCHAIN_HASH = '1023ce2e82'
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
json_data_file = os.path.join(script_dir, 'win_toolchain.json')
|
||||
|
||||
# VS versions are listed in descending order of priority (highest first).
|
||||
# The first version is assumed by this script to be the one that is packaged,
|
||||
# which makes a difference for the arm64 runtime.
|
||||
MSVS_VERSIONS = collections.OrderedDict([
|
||||
('2022', '17.0'), # Default and packaged version of Visual Studio.
|
||||
('2019', '16.0'),
|
||||
('2017', '15.0'),
|
||||
])
|
||||
|
||||
# List of preferred VC toolset version based on MSVS
|
||||
# Order is not relevant for this dictionary.
|
||||
MSVC_TOOLSET_VERSION = {
|
||||
'2022': 'VC143',
|
||||
'2019': 'VC142',
|
||||
'2017': 'VC141',
|
||||
}
|
||||
|
||||
def _HostIsWindows():
|
||||
"""Returns True if running on a Windows host (including under cygwin)."""
|
||||
return sys.platform in ('win32', 'cygwin')
|
||||
|
||||
def SetEnvironmentAndGetRuntimeDllDirs():
|
||||
"""Sets up os.environ to use the depot_tools VS toolchain with gyp, and
|
||||
returns the location of the VC runtime DLLs so they can be copied into
|
||||
the output directory after gyp generation.
|
||||
|
||||
Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is
|
||||
generated separately because there are multiple folders for the arm64 VC
|
||||
runtime.
|
||||
"""
|
||||
vs_runtime_dll_dirs = None
|
||||
depot_tools_win_toolchain = \
|
||||
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
|
||||
# When running on a non-Windows host, only do this if the SDK has explicitly
|
||||
# been downloaded before (in which case json_data_file will exist).
|
||||
if ((_HostIsWindows() or os.path.exists(json_data_file))
|
||||
and depot_tools_win_toolchain):
|
||||
if ShouldUpdateToolchain():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'update':
|
||||
update_result = Update()
|
||||
else:
|
||||
update_result = Update(no_download=True)
|
||||
if update_result != 0:
|
||||
raise Exception('Failed to update, error code %d.' % update_result)
|
||||
with open(json_data_file, 'r') as tempf:
|
||||
toolchain_data = json.load(tempf)
|
||||
|
||||
toolchain = toolchain_data['path']
|
||||
version = toolchain_data['version']
|
||||
win_sdk = toolchain_data.get('win_sdk')
|
||||
wdk = toolchain_data['wdk']
|
||||
# TODO(scottmg): The order unfortunately matters in these. They should be
|
||||
# split into separate keys for x64/x86/arm64. (See CopyDlls call below).
|
||||
# http://crbug.com/345992
|
||||
vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
|
||||
# The number of runtime_dirs in the toolchain_data was two (x64/x86) but
|
||||
# changed to three (x64/x86/arm64) and this code needs to handle both
|
||||
# possibilities, which can change independently from this code.
|
||||
if len(vs_runtime_dll_dirs) == 2:
|
||||
vs_runtime_dll_dirs.append('Arm64Unused')
|
||||
|
||||
os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
|
||||
|
||||
os.environ['WINDOWSSDKDIR'] = win_sdk
|
||||
os.environ['WDK_DIR'] = wdk
|
||||
# Include the VS runtime in the PATH in case it's not machine-installed.
|
||||
runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs)
|
||||
os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH']
|
||||
elif sys.platform == 'win32' and not depot_tools_win_toolchain:
|
||||
if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ:
|
||||
os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
|
||||
|
||||
# When using an installed toolchain these files aren't needed in the output
|
||||
# directory in order to run binaries locally, but they are needed in order
|
||||
# to create isolates or the mini_installer. Copying them to the output
|
||||
# directory ensures that they are available when needed.
|
||||
bitness = platform.architecture()[0]
|
||||
# When running 64-bit python the x64 DLLs will be in System32
|
||||
# ARM64 binaries will not be available in the system directories because we
|
||||
# don't build on ARM64 machines.
|
||||
x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
|
||||
x64_path = os.path.join(os.path.expandvars('%windir%'), x64_path)
|
||||
vs_runtime_dll_dirs = [x64_path,
|
||||
os.path.join(os.path.expandvars('%windir%'),
|
||||
'SysWOW64'),
|
||||
'Arm64Unused']
|
||||
|
||||
return vs_runtime_dll_dirs
|
||||
|
||||
|
||||
def _RegistryGetValueUsingWinReg(key, value):
|
||||
"""Use the _winreg module to obtain the value of a registry key.
|
||||
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure. Throws
|
||||
ImportError if _winreg is unavailable.
|
||||
"""
|
||||
import _winreg
|
||||
try:
|
||||
root, subkey = key.split('\\', 1)
|
||||
assert root == 'HKLM' # Only need HKLM for now.
|
||||
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
|
||||
return _winreg.QueryValueEx(hkey, value)[0]
|
||||
except WindowsError:
|
||||
return None
|
||||
|
||||
|
||||
def _RegistryGetValue(key, value):
|
||||
try:
|
||||
return _RegistryGetValueUsingWinReg(key, value)
|
||||
except ImportError:
|
||||
raise Exception('The python library _winreg not found.')
|
||||
|
||||
|
||||
def GetVisualStudioVersion():
|
||||
"""Return best available version of Visual Studio.
|
||||
"""
|
||||
supported_versions = list(MSVS_VERSIONS.keys())
|
||||
|
||||
# VS installed in depot_tools for Googlers
|
||||
if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))):
|
||||
return supported_versions[0]
|
||||
|
||||
# VS installed in system for external developers
|
||||
supported_versions_str = ', '.join('{} ({})'.format(v,k)
|
||||
for k,v in MSVS_VERSIONS.items())
|
||||
available_versions = []
|
||||
for version in supported_versions:
|
||||
# Checking vs%s_install environment variables.
|
||||
# For example, vs2019_install could have the value
|
||||
# "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community".
|
||||
# Only vs2017_install, vs2019_install and vs2022_install are supported.
|
||||
path = os.environ.get('vs%s_install' % version)
|
||||
if path and os.path.exists(path):
|
||||
available_versions.append(version)
|
||||
break
|
||||
# Detecting VS under possible paths.
|
||||
if version >= '2022':
|
||||
program_files_path_variable = '%ProgramFiles%'
|
||||
else:
|
||||
program_files_path_variable = '%ProgramFiles(x86)%'
|
||||
path = os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s' % version)
|
||||
if path and any(
|
||||
os.path.exists(os.path.join(path, edition))
|
||||
for edition in ('Enterprise', 'Professional', 'Community', 'Preview',
|
||||
'BuildTools')):
|
||||
available_versions.append(version)
|
||||
break
|
||||
|
||||
if not available_versions:
|
||||
raise Exception('No supported Visual Studio can be found.'
|
||||
' Supported versions are: %s.' % supported_versions_str)
|
||||
return available_versions[0]
|
||||
|
||||
|
||||
def DetectVisualStudioPath():
|
||||
"""Return path to the installed Visual Studio.
|
||||
"""
|
||||
|
||||
# Note that this code is used from
|
||||
# build/toolchain/win/setup_toolchain.py as well.
|
||||
version_as_year = GetVisualStudioVersion()
|
||||
|
||||
# The VC++ >=2017 install location needs to be located using COM instead of
|
||||
# the registry. For details see:
|
||||
# https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
|
||||
# For now we use a hardcoded default with an environment variable override.
|
||||
if version_as_year >= '2022':
|
||||
program_files_path_variable = '%ProgramFiles%'
|
||||
else:
|
||||
program_files_path_variable = '%ProgramFiles(x86)%'
|
||||
for path in (os.environ.get('vs%s_install' % version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Enterprise' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Professional' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Community' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Preview' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/BuildTools' %
|
||||
version_as_year)):
|
||||
if path and os.path.exists(path):
|
||||
return path
|
||||
|
||||
raise Exception('Visual Studio Version %s not found.' % version_as_year)
|
||||
|
||||
|
||||
def _CopyRuntimeImpl(target, source, verbose=True):
|
||||
"""Copy |source| to |target| if it doesn't already exist or if it needs to be
|
||||
updated (comparing last modified time as an approximate float match as for
|
||||
some reason the values tend to differ by ~1e-07 despite being copies of the
|
||||
same file... https://crbug.com/603603).
|
||||
"""
|
||||
if (os.path.isdir(os.path.dirname(target)) and
|
||||
(not os.path.isfile(target) or
|
||||
abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)):
|
||||
if verbose:
|
||||
print('Copying %s to %s...' % (source, target))
|
||||
if os.path.exists(target):
|
||||
# Make the file writable so that we can delete it now, and keep it
|
||||
# readable.
|
||||
os.chmod(target, stat.S_IWRITE | stat.S_IREAD)
|
||||
os.unlink(target)
|
||||
shutil.copy2(source, target)
|
||||
# Make the file writable so that we can overwrite or delete it later,
|
||||
# keep it readable.
|
||||
os.chmod(target, stat.S_IWRITE | stat.S_IREAD)
|
||||
|
||||
def _SortByHighestVersionNumberFirst(list_of_str_versions):
|
||||
"""This sorts |list_of_str_versions| according to version number rules
|
||||
so that version "1.12" is higher than version "1.9". Does not work
|
||||
with non-numeric versions like 1.4.a8 which will be higher than
|
||||
1.4.a12. It does handle the versions being embedded in file paths.
|
||||
"""
|
||||
def to_int_if_int(x):
|
||||
try:
|
||||
return int(x)
|
||||
except ValueError:
|
||||
return x
|
||||
|
||||
def to_number_sequence(x):
|
||||
part_sequence = re.split(r'[\\/\.]', x)
|
||||
return [to_int_if_int(x) for x in part_sequence]
|
||||
|
||||
list_of_str_versions.sort(key=to_number_sequence, reverse=True)
|
||||
|
||||
|
||||
def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix):
|
||||
"""Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't
|
||||
exist, but the target directory does exist."""
|
||||
if target_cpu == 'arm64':
|
||||
# Windows ARM64 VCRuntime is located at {toolchain_root}/VC/Redist/MSVC/
|
||||
# {x.y.z}/[debug_nonredist/]arm64/Microsoft.VC14x.CRT/.
|
||||
# Select VC toolset directory based on Visual Studio version
|
||||
vc_redist_root = FindVCRedistRoot()
|
||||
if suffix.startswith('.'):
|
||||
vc_toolset_dir = 'Microsoft.{}.CRT' \
|
||||
.format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()])
|
||||
source_dir = os.path.join(vc_redist_root,
|
||||
'arm64', vc_toolset_dir)
|
||||
else:
|
||||
vc_toolset_dir = 'Microsoft.{}.DebugCRT' \
|
||||
.format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()])
|
||||
source_dir = os.path.join(vc_redist_root, 'debug_nonredist',
|
||||
'arm64', vc_toolset_dir)
|
||||
file_parts = ('msvcp140', 'vccorlib140', 'vcruntime140')
|
||||
if target_cpu == 'x64' and GetVisualStudioVersion() != '2017':
|
||||
file_parts = file_parts + ('vcruntime140_1', )
|
||||
for file_part in file_parts:
|
||||
dll = file_part + suffix
|
||||
target = os.path.join(target_dir, dll)
|
||||
source = os.path.join(source_dir, dll)
|
||||
_CopyRuntimeImpl(target, source)
|
||||
# Copy the UCRT files from the Windows SDK. This location includes the
|
||||
# api-ms-win-crt-*.dll files that are not found in the Windows directory.
|
||||
# These files are needed for component builds. If WINDOWSSDKDIR is not set
|
||||
# use the default SDK path. This will be the case when
|
||||
# DEPOT_TOOLS_WIN_TOOLCHAIN=0 and vcvarsall.bat has not been run.
|
||||
win_sdk_dir = os.path.normpath(
|
||||
os.environ.get('WINDOWSSDKDIR',
|
||||
os.path.expandvars('%ProgramFiles(x86)%'
|
||||
'\\Windows Kits\\10')))
|
||||
# ARM64 doesn't have a redist for the ucrt DLLs because they are always
|
||||
# present in the OS.
|
||||
if target_cpu != 'arm64':
|
||||
# Starting with the 10.0.17763 SDK the ucrt files are in a version-named
|
||||
# directory - this handles both cases.
|
||||
redist_dir = os.path.join(win_sdk_dir, 'Redist')
|
||||
version_dirs = glob.glob(os.path.join(redist_dir, '10.*'))
|
||||
if len(version_dirs) > 0:
|
||||
_SortByHighestVersionNumberFirst(version_dirs)
|
||||
redist_dir = version_dirs[0]
|
||||
ucrt_dll_dirs = os.path.join(redist_dir, 'ucrt', 'DLLs', target_cpu)
|
||||
ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
|
||||
assert len(ucrt_files) > 0
|
||||
for ucrt_src_file in ucrt_files:
|
||||
file_part = os.path.basename(ucrt_src_file)
|
||||
ucrt_dst_file = os.path.join(target_dir, file_part)
|
||||
_CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
|
||||
# We must copy ucrtbase.dll for x64/x86, and ucrtbased.dll for all CPU types.
|
||||
if target_cpu != 'arm64' or not suffix.startswith('.'):
|
||||
if not suffix.startswith('.'):
|
||||
# ucrtbased.dll is located at {win_sdk_dir}/bin/{a.b.c.d}/{target_cpu}/
|
||||
# ucrt/.
|
||||
sdk_bin_root = os.path.join(win_sdk_dir, 'bin')
|
||||
sdk_bin_sub_dirs = glob.glob(os.path.join(sdk_bin_root, '10.*'))
|
||||
# Select the most recent SDK if there are multiple versions installed.
|
||||
_SortByHighestVersionNumberFirst(sdk_bin_sub_dirs)
|
||||
for directory in sdk_bin_sub_dirs:
|
||||
sdk_redist_root_version = os.path.join(sdk_bin_root, directory)
|
||||
if not os.path.isdir(sdk_redist_root_version):
|
||||
continue
|
||||
source_dir = os.path.join(sdk_redist_root_version, target_cpu, 'ucrt')
|
||||
break
|
||||
_CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
|
||||
os.path.join(source_dir, 'ucrtbase' + suffix))
|
||||
|
||||
|
||||
def FindVCComponentRoot(component):
|
||||
"""Find the most recent Tools or Redist or other directory in an MSVC install.
|
||||
Typical results are {toolchain_root}/VC/{component}/MSVC/{x.y.z}. The {x.y.z}
|
||||
version number part changes frequently so the highest version number found is
|
||||
used.
|
||||
"""
|
||||
|
||||
SetEnvironmentAndGetRuntimeDllDirs()
|
||||
assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ)
|
||||
vc_component_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
|
||||
'VC', component, 'MSVC')
|
||||
vc_component_msvc_contents = glob.glob(
|
||||
os.path.join(vc_component_msvc_root, '14.*'))
|
||||
# Select the most recent toolchain if there are several.
|
||||
_SortByHighestVersionNumberFirst(vc_component_msvc_contents)
|
||||
for directory in vc_component_msvc_contents:
|
||||
if os.path.isdir(directory):
|
||||
return directory
|
||||
raise Exception('Unable to find the VC %s directory.' % component)
|
||||
|
||||
|
||||
def FindVCRedistRoot():
|
||||
"""In >=VS2017, Redist binaries are located in
|
||||
{toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/.
|
||||
|
||||
This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path.
|
||||
"""
|
||||
return FindVCComponentRoot('Redist')
|
||||
|
||||
|
||||
def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
|
||||
"""Copy the VS runtime DLLs, only if the target doesn't exist, but the target
|
||||
directory does exist. Handles VS 2015, 2017 and 2019."""
|
||||
suffix = 'd.dll' if debug else '.dll'
|
||||
# VS 2015, 2017 and 2019 use the same CRT DLLs.
|
||||
_CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix)
|
||||
|
||||
|
||||
def CopyDlls(target_dir, configuration, target_cpu):
|
||||
"""Copy the VS runtime DLLs into the requested directory as needed.
|
||||
|
||||
configuration is one of 'Debug' or 'Release'.
|
||||
target_cpu is one of 'x86', 'x64' or 'arm64'.
|
||||
|
||||
The debug configuration gets both the debug and release DLLs; the
|
||||
release config only the latter.
|
||||
"""
|
||||
vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
|
||||
if not vs_runtime_dll_dirs:
|
||||
return
|
||||
|
||||
x64_runtime, x86_runtime, arm64_runtime = vs_runtime_dll_dirs
|
||||
if target_cpu == 'x64':
|
||||
runtime_dir = x64_runtime
|
||||
elif target_cpu == 'x86':
|
||||
runtime_dir = x86_runtime
|
||||
elif target_cpu == 'arm64':
|
||||
runtime_dir = arm64_runtime
|
||||
else:
|
||||
raise Exception('Unknown target_cpu: ' + target_cpu)
|
||||
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
|
||||
if configuration == 'Debug':
|
||||
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
|
||||
_CopyDebugger(target_dir, target_cpu)
|
||||
|
||||
|
||||
def _CopyDebugger(target_dir, target_cpu):
|
||||
"""Copy dbghelp.dll and dbgcore.dll into the requested directory as needed.
|
||||
|
||||
target_cpu is one of 'x86', 'x64' or 'arm64'.
|
||||
|
||||
dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
|
||||
from the SDK directory avoids using the system copy of dbghelp.dll which then
|
||||
ensures compatibility with recent debug information formats, such as VS
|
||||
2017 /debug:fastlink PDBs.
|
||||
|
||||
dbgcore.dll is needed when using some functions from dbghelp.dll (like
|
||||
MinidumpWriteDump).
|
||||
"""
|
||||
win_sdk_dir = SetEnvironmentAndGetSDKDir()
|
||||
if not win_sdk_dir:
|
||||
return
|
||||
|
||||
# List of debug files that should be copied, the first element of the tuple is
|
||||
# the name of the file and the second indicates if it's optional.
|
||||
debug_files = [('dbghelp.dll', False), ('dbgcore.dll', True)]
|
||||
# The UCRT is not a redistributable component on arm64.
|
||||
if target_cpu != 'arm64':
|
||||
debug_files.extend([('api-ms-win-downlevel-kernel32-l2-1-0.dll', False),
|
||||
('api-ms-win-eventing-provider-l1-1-0.dll', False)])
|
||||
for debug_file, is_optional in debug_files:
|
||||
full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, debug_file)
|
||||
if not os.path.exists(full_path):
|
||||
if is_optional:
|
||||
continue
|
||||
else:
|
||||
raise Exception('%s not found in "%s"\r\nYou must install '
|
||||
'Windows 10 SDK version 10.0.20348.0 including the '
|
||||
'"Debugging Tools for Windows" feature.' %
|
||||
(debug_file, full_path))
|
||||
target_path = os.path.join(target_dir, debug_file)
|
||||
_CopyRuntimeImpl(target_path, full_path)
|
||||
|
||||
|
||||
def _GetDesiredVsToolchainHashes():
|
||||
"""Load a list of SHA1s corresponding to the toolchains that we want installed
|
||||
to build with."""
|
||||
# Third parties that do not have access to the canonical toolchain can map
|
||||
# canonical toolchain version to their own toolchain versions.
|
||||
toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % TOOLCHAIN_HASH
|
||||
return [os.environ.get(toolchain_hash_mapping_key, TOOLCHAIN_HASH)]
|
||||
|
||||
|
||||
def ShouldUpdateToolchain():
|
||||
"""Check if the toolchain should be upgraded."""
|
||||
if not os.path.exists(json_data_file):
|
||||
return True
|
||||
with open(json_data_file, 'r') as tempf:
|
||||
toolchain_data = json.load(tempf)
|
||||
version = toolchain_data['version']
|
||||
env_version = GetVisualStudioVersion()
|
||||
# If there's a mismatch between the version set in the environment and the one
|
||||
# in the json file then the toolchain should be updated.
|
||||
return version != env_version
|
||||
|
||||
|
||||
def Update(force=False, no_download=False):
|
||||
"""Requests an update of the toolchain to the specific hashes we have at
|
||||
this revision. The update outputs a .json of the various configuration
|
||||
information required to pass to gyp which we use in |GetToolchainDir()|.
|
||||
If no_download is true then the toolchain will be configured if present but
|
||||
will not be downloaded.
|
||||
"""
|
||||
if force != False and force != '--force':
|
||||
print('Unknown parameter "%s"' % force, file=sys.stderr)
|
||||
return 1
|
||||
if force == '--force' or os.path.exists(json_data_file):
|
||||
force = True
|
||||
|
||||
depot_tools_win_toolchain = \
|
||||
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
|
||||
if (_HostIsWindows() or force) and depot_tools_win_toolchain:
|
||||
import find_depot_tools
|
||||
depot_tools_path = find_depot_tools.add_depot_tools_to_path()
|
||||
|
||||
# On Linux, the file system is usually case-sensitive while the Windows
|
||||
# SDK only works on case-insensitive file systems. If it doesn't already
|
||||
# exist, set up a ciopfs fuse mount to put the SDK in a case-insensitive
|
||||
# part of the file system.
|
||||
toolchain_dir = os.path.join(depot_tools_path, 'win_toolchain', 'vs_files')
|
||||
# For testing this block, unmount existing mounts with
|
||||
# fusermount -u third_party/depot_tools/win_toolchain/vs_files
|
||||
if sys.platform.startswith('linux') and not os.path.ismount(toolchain_dir):
|
||||
import distutils.spawn
|
||||
ciopfs = distutils.spawn.find_executable('ciopfs')
|
||||
if not ciopfs:
|
||||
# ciopfs not found in PATH; try the one downloaded from the DEPS hook.
|
||||
ciopfs = os.path.join(script_dir, 'ciopfs')
|
||||
if not os.path.isdir(toolchain_dir):
|
||||
os.mkdir(toolchain_dir)
|
||||
if not os.path.isdir(toolchain_dir + '.ciopfs'):
|
||||
os.mkdir(toolchain_dir + '.ciopfs')
|
||||
# Without use_ino, clang's #pragma once and Wnonportable-include-path
|
||||
# both don't work right, see https://llvm.org/PR34931
|
||||
# use_ino doesn't slow down builds, so it seems there's no drawback to
|
||||
# just using it always.
|
||||
subprocess.check_call([
|
||||
ciopfs, '-o', 'use_ino', toolchain_dir + '.ciopfs', toolchain_dir])
|
||||
|
||||
get_toolchain_args = [
|
||||
sys.executable,
|
||||
os.path.join(depot_tools_path,
|
||||
'win_toolchain',
|
||||
'get_toolchain_if_necessary.py'),
|
||||
'--output-json', json_data_file,
|
||||
] + _GetDesiredVsToolchainHashes()
|
||||
if force:
|
||||
get_toolchain_args.append('--force')
|
||||
if no_download:
|
||||
get_toolchain_args.append('--no-download')
|
||||
subprocess.check_call(get_toolchain_args)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def NormalizePath(path):
|
||||
while path.endswith('\\'):
|
||||
path = path[:-1]
|
||||
return path
|
||||
|
||||
|
||||
def SetEnvironmentAndGetSDKDir():
|
||||
"""Gets location information about the current sdk (must have been
|
||||
previously updated by 'update'). This is used for the GN build."""
|
||||
SetEnvironmentAndGetRuntimeDllDirs()
|
||||
|
||||
# If WINDOWSSDKDIR is not set, search the default SDK path and set it.
|
||||
if not 'WINDOWSSDKDIR' in os.environ:
|
||||
default_sdk_path = os.path.expandvars('%ProgramFiles(x86)%'
|
||||
'\\Windows Kits\\10')
|
||||
if os.path.isdir(default_sdk_path):
|
||||
os.environ['WINDOWSSDKDIR'] = default_sdk_path
|
||||
|
||||
return NormalizePath(os.environ['WINDOWSSDKDIR'])
|
||||
|
||||
|
||||
def GetToolchainDir():
|
||||
"""Gets location information about the current toolchain (must have been
|
||||
previously updated by 'update'). This is used for the GN build."""
|
||||
runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
|
||||
win_sdk_dir = SetEnvironmentAndGetSDKDir()
|
||||
|
||||
print('''vs_path = %s
|
||||
sdk_path = %s
|
||||
vs_version = %s
|
||||
wdk_dir = %s
|
||||
runtime_dirs = %s
|
||||
''' % (ToGNString(NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH'])),
|
||||
ToGNString(win_sdk_dir), ToGNString(GetVisualStudioVersion()),
|
||||
ToGNString(NormalizePath(os.environ.get('WDK_DIR', ''))),
|
||||
ToGNString(os.path.pathsep.join(runtime_dll_dirs or ['None']))))
|
||||
|
||||
|
||||
def main():
|
||||
commands = {
|
||||
'update': Update,
|
||||
'get_toolchain_dir': GetToolchainDir,
|
||||
'copy_dlls': CopyDlls,
|
||||
}
|
||||
if len(sys.argv) < 2 or sys.argv[1] not in commands:
|
||||
print('Expected one of: %s' % ', '.join(commands), file=sys.stderr)
|
||||
return 1
|
||||
return commands[sys.argv[1]](*sys.argv[2:])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
98
src/build/win/reorder-imports.py
Normal file
98
src/build/win/reorder-imports.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2022 The Chromium Authors, Alex313031, and gz83. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import glob
|
||||
import optparse
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.join(os.path.dirname(__file__), '..', '..', 'third_party',
|
||||
'pefile_py3'))
|
||||
import pefile
|
||||
|
||||
def reorder_imports(input_dir, output_dir, architecture):
|
||||
"""Swap chrome_elf.dll to be the first import of chrome.exe.
|
||||
Also copy over any related files that might be needed
|
||||
(pdbs, manifests etc.).
|
||||
"""
|
||||
# TODO(thakis): See if there is a reliable way to write the
|
||||
# correct executable in the first place, so that this script
|
||||
# only needs to verify that and not write a whole new exe.
|
||||
|
||||
input_image = os.path.join(input_dir, 'thorium.exe')
|
||||
output_image = os.path.join(output_dir, 'thorium.exe')
|
||||
|
||||
# pefile mmap()s the whole executable, and then parses parts of
|
||||
# it into python data structures for ease of processing.
|
||||
# To write the file again, only the mmap'd data is written back,
|
||||
# so modifying the parsed python objects generally has no effect.
|
||||
# However, parsed raw data ends up in pe.Structure instances,
|
||||
# and these all get serialized back when the file gets written.
|
||||
# So things that are in a Structure must have their data set
|
||||
# through the Structure, while other data must bet set through
|
||||
# the set_bytes_*() methods.
|
||||
pe = pefile.PE(input_image, fast_load=True)
|
||||
if architecture == 'x64' or architecture == 'arm64':
|
||||
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS
|
||||
else:
|
||||
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE
|
||||
|
||||
pe.parse_data_directories(directories=[
|
||||
pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT']])
|
||||
|
||||
found_elf = False
|
||||
for i, peimport in enumerate(pe.DIRECTORY_ENTRY_IMPORT):
|
||||
if peimport.dll.lower() == b'chrome_elf.dll':
|
||||
assert not found_elf, 'only one chrome_elf.dll import expected'
|
||||
found_elf = True
|
||||
if i > 0:
|
||||
swap = pe.DIRECTORY_ENTRY_IMPORT[0]
|
||||
|
||||
# Morally we want to swap peimport.struct and swap.struct here,
|
||||
# but the pe module doesn't expose a public method on Structure
|
||||
# to get all data of a Structure without explicitly listing all
|
||||
# field names.
|
||||
# NB: OriginalFirstThunk and Characteristics are an union both at
|
||||
# offset 0, handling just one of them is enough.
|
||||
peimport.struct.OriginalFirstThunk, swap.struct.OriginalFirstThunk = \
|
||||
swap.struct.OriginalFirstThunk, peimport.struct.OriginalFirstThunk
|
||||
peimport.struct.TimeDateStamp, swap.struct.TimeDateStamp = \
|
||||
swap.struct.TimeDateStamp, peimport.struct.TimeDateStamp
|
||||
peimport.struct.ForwarderChain, swap.struct.ForwarderChain = \
|
||||
swap.struct.ForwarderChain, peimport.struct.ForwarderChain
|
||||
peimport.struct.Name, swap.struct.Name = \
|
||||
swap.struct.Name, peimport.struct.Name
|
||||
peimport.struct.FirstThunk, swap.struct.FirstThunk = \
|
||||
swap.struct.FirstThunk, peimport.struct.FirstThunk
|
||||
assert found_elf, 'chrome_elf.dll import not found'
|
||||
|
||||
pe.write(filename=output_image)
|
||||
|
||||
for fname in glob.iglob(os.path.join(input_dir, 'thorium.exe.*')):
|
||||
shutil.copy(fname, os.path.join(output_dir, os.path.basename(fname)))
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv):
|
||||
usage = 'reorder_imports.py -i <input_dir> -o <output_dir> -a <target_arch>'
|
||||
parser = optparse.OptionParser(usage=usage)
|
||||
parser.add_option('-i', '--input', help='reorder thorium.exe in DIR',
|
||||
metavar='DIR')
|
||||
parser.add_option('-o', '--output', help='write new thorium.exe to DIR',
|
||||
metavar='DIR')
|
||||
parser.add_option('-a', '--arch', help='architecture of build (optional)',
|
||||
default='ia32')
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
if not opts.input or not opts.output:
|
||||
parser.error('Please provide and input and output directory')
|
||||
return reorder_imports(opts.input, opts.output, opts.arch)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
199
src/content/browser/launch_as_mojo_client_browsertest.cc
Normal file
199
src/content/browser/launch_as_mojo_client_browsertest.cc
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2022 The Chromium Authors and Alex313031. 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/base_switches.h"
|
||||
#include "base/cfi_buildflags.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/test/bind.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/test/browser_test.h"
|
||||
#include "content/public/test/content_browser_test.h"
|
||||
#include "content/shell/common/shell_controller.test-mojom.h"
|
||||
#include "content/shell/common/shell_switches.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "mojo/public/cpp/platform/platform_channel.h"
|
||||
#include "mojo/public/cpp/system/invitation.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/ozone/public/ozone_switches.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#include "ui/gl/gl_switches.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const char kShellExecutableName[] = "thorium_shell.exe";
|
||||
#else
|
||||
const char kShellExecutableName[] = "thorium_shell";
|
||||
const char kMojoCoreLibraryName[] = "libmojo_core.so";
|
||||
#endif
|
||||
|
||||
base::FilePath GetCurrentDirectory() {
|
||||
base::FilePath current_directory;
|
||||
CHECK(base::GetCurrentDirectory(¤t_directory));
|
||||
return current_directory;
|
||||
}
|
||||
|
||||
class LaunchAsMojoClientBrowserTest : public ContentBrowserTest {
|
||||
public:
|
||||
LaunchAsMojoClientBrowserTest() { CHECK(temp_dir_.CreateUniqueTempDir()); }
|
||||
|
||||
~LaunchAsMojoClientBrowserTest() override {
|
||||
// Ensure that the launched Content Shell process is dead before the test
|
||||
// tears down, otherwise the temp profile dir may fail to delete. Note that
|
||||
// tests must explicitly request shutdown through ShellController before
|
||||
// finishing, otherwise this will time out.
|
||||
CHECK(content_shell_process_.WaitForExit(nullptr));
|
||||
CHECK(temp_dir_.Delete());
|
||||
}
|
||||
|
||||
base::CommandLine MakeShellCommandLine() {
|
||||
base::CommandLine command_line(
|
||||
GetFilePathNextToCurrentExecutable(kShellExecutableName));
|
||||
command_line.AppendSwitchPath(switches::kContentShellDataPath,
|
||||
temp_dir_.GetPath());
|
||||
#if defined(USE_OZONE)
|
||||
const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
|
||||
const char* kSwitchesToCopy[] = {
|
||||
// Keep the kOzonePlatform switch that the Ozone must use.
|
||||
switches::kOzonePlatform,
|
||||
};
|
||||
command_line.CopySwitchesFrom(cmdline, kSwitchesToCopy,
|
||||
std::size(kSwitchesToCopy));
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
command_line.AppendSwitchASCII(switches::kUseGL,
|
||||
gl::kGLImplementationANGLEName);
|
||||
command_line.AppendSwitchASCII(switches::kUseANGLE,
|
||||
gl::kANGLEImplementationSwiftShaderName);
|
||||
#endif
|
||||
return command_line;
|
||||
}
|
||||
|
||||
mojo::Remote<mojom::ShellController> LaunchContentShell(
|
||||
const base::CommandLine& command_line) {
|
||||
mojo::PlatformChannel channel;
|
||||
base::LaunchOptions options;
|
||||
base::CommandLine shell_command_line(command_line);
|
||||
channel.PrepareToPassRemoteEndpoint(&options, &shell_command_line);
|
||||
content_shell_process_ = base::LaunchProcess(shell_command_line, options);
|
||||
channel.RemoteProcessLaunchAttempted();
|
||||
|
||||
mojo::OutgoingInvitation invitation;
|
||||
mojo::Remote<mojom::ShellController> controller(
|
||||
mojo::PendingRemote<mojom::ShellController>(
|
||||
invitation.AttachMessagePipe(0), /*version=*/0));
|
||||
mojo::OutgoingInvitation::Send(std::move(invitation),
|
||||
content_shell_process_.Handle(),
|
||||
channel.TakeLocalEndpoint());
|
||||
return controller;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
base::FilePath GetMojoCoreLibraryPath() {
|
||||
return GetFilePathNextToCurrentExecutable(kMojoCoreLibraryName);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
base::FilePath GetFilePathNextToCurrentExecutable(
|
||||
const std::string& filename) {
|
||||
base::FilePath executable_dir =
|
||||
base::CommandLine::ForCurrentProcess()->GetProgram().DirName();
|
||||
if (executable_dir.IsAbsolute())
|
||||
return executable_dir.AppendASCII(filename);
|
||||
|
||||
// If the current executable path is relative, resolve it to an absolute
|
||||
// path before swapping in |filename|. This ensures that the path is OK to
|
||||
// use with base::LaunchProcess. Otherwise we could end up with a path
|
||||
// containing only |filename|, and this can fail to execute in environments
|
||||
// where "." is not in the PATH (common on e.g. Linux).
|
||||
return current_directory_.Append(executable_dir).AppendASCII(filename);
|
||||
}
|
||||
|
||||
base::ScopedTempDir temp_dir_;
|
||||
const base::FilePath current_directory_ = GetCurrentDirectory();
|
||||
base::Process content_shell_process_;
|
||||
mojo::Remote<mojom::ShellController> shell_controller_;
|
||||
};
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest, LaunchAndBindInterface) {
|
||||
// Verifies that we can launch an instance of Content Shell with a Mojo
|
||||
// invitation on the command line and reach the new browser process's exposed
|
||||
// ShellController interface.
|
||||
|
||||
const char kExtraSwitchName[] = "extra-switch-for-testing";
|
||||
const char kExtraSwitchValue[] = "42";
|
||||
|
||||
base::CommandLine command_line = MakeShellCommandLine();
|
||||
command_line.AppendSwitchASCII(kExtraSwitchName, kExtraSwitchValue);
|
||||
mojo::Remote<mojom::ShellController> shell_controller =
|
||||
LaunchContentShell(command_line);
|
||||
|
||||
base::RunLoop loop;
|
||||
shell_controller->GetSwitchValue(
|
||||
kExtraSwitchName,
|
||||
base::BindLambdaForTesting([&](const absl::optional<std::string>& value) {
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ(kExtraSwitchValue, *value);
|
||||
loop.Quit();
|
||||
}));
|
||||
loop.Run();
|
||||
|
||||
shell_controller->ShutDown();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
// TODO(crbug.com/1259557): This test implementation fundamentally conflicts
|
||||
// with a fix for the linked bug because it causes a browser process to behave
|
||||
// partially as a broker and partially as a non-broker. This can be re-enabled
|
||||
// when we migrate away from the current Mojo implementation. It's OK to disable
|
||||
// for now because no production code relies on this feature.
|
||||
IN_PROC_BROWSER_TEST_F(LaunchAsMojoClientBrowserTest,
|
||||
DISABLED_WithMojoCoreLibrary) {
|
||||
// Instructs a newly launched Content Shell browser to initialize Mojo Core
|
||||
// dynamically from a shared library, rather than using the version linked
|
||||
// into the Content Shell binary.
|
||||
//
|
||||
// This exercises end-to-end JS in order to cover real IPC behavior between
|
||||
// the browser and a renderer.
|
||||
|
||||
base::CommandLine command_line = MakeShellCommandLine();
|
||||
command_line.AppendSwitchPath(switches::kMojoCoreLibraryPath,
|
||||
GetMojoCoreLibraryPath());
|
||||
mojo::Remote<mojom::ShellController> shell_controller =
|
||||
LaunchContentShell(command_line);
|
||||
|
||||
// Indisputable proof that we're evaluating JavaScript.
|
||||
const std::string kExpressionToEvaluate = "'ba'+ +'a'+'as'";
|
||||
const base::Value kExpectedValue("baNaNas");
|
||||
|
||||
base::RunLoop loop;
|
||||
shell_controller->ExecuteJavaScript(
|
||||
base::ASCIIToUTF16(kExpressionToEvaluate),
|
||||
base::BindLambdaForTesting([&](base::Value value) {
|
||||
EXPECT_EQ(kExpectedValue, value);
|
||||
loop.Quit();
|
||||
}));
|
||||
loop.Run();
|
||||
|
||||
shell_controller->ShutDown();
|
||||
}
|
||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
|
||||
} // namespace
|
||||
} // namespace content
|
145
src/content/gpu/BUILD.gn
Normal file
145
src/content/gpu/BUILD.gn
Normal file
|
@ -0,0 +1,145 @@
|
|||
# Copyright 2022 The Chromium Authors and Alex313031. 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/chromeos/ui_mode.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//gpu/vulkan/features.gni")
|
||||
import("//media/media_options.gni")
|
||||
import("//media/gpu/args.gni")
|
||||
|
||||
# See //content/BUILD.gn for how this works.
|
||||
group("gpu") {
|
||||
visibility = [ "//content/*" ] # This is an internal content API.
|
||||
|
||||
if (is_component_build) {
|
||||
public_deps = [ "//content" ]
|
||||
} else {
|
||||
public_deps = [ ":gpu_sources" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_component_build) {
|
||||
link_target_type = "source_set"
|
||||
} else {
|
||||
link_target_type = "static_library"
|
||||
}
|
||||
|
||||
target(link_target_type, "gpu_sources") {
|
||||
# This is an internal content API. Code outside of the content "component"
|
||||
# (like content/test and content/shell) should depend on ":gpu" above.
|
||||
visibility = [ "//content/*" ]
|
||||
|
||||
sources = [
|
||||
"browser_exposed_gpu_interfaces.cc",
|
||||
"browser_exposed_gpu_interfaces.h",
|
||||
"gpu_child_thread.cc",
|
||||
"gpu_child_thread.h",
|
||||
"gpu_child_thread_receiver_bindings.cc",
|
||||
"gpu_main.cc",
|
||||
"gpu_service_factory.cc",
|
||||
"gpu_service_factory.h",
|
||||
"in_process_gpu_thread.cc",
|
||||
"in_process_gpu_thread.h",
|
||||
]
|
||||
|
||||
configs += [ "//content:content_implementation" ]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//base/third_party/dynamic_annotations",
|
||||
"//build:branding_buildflags",
|
||||
"//build:chromeos_buildflags",
|
||||
"//components/viz/service",
|
||||
"//content:export",
|
||||
"//content/child",
|
||||
"//content/common",
|
||||
"//content/common:mojo_bindings",
|
||||
"//content/public/child:child_sources",
|
||||
"//content/public/common:common_sources",
|
||||
"//gpu:gpu",
|
||||
"//gpu/ipc/common:command_buffer_traits",
|
||||
"//gpu/ipc/service",
|
||||
"//ipc",
|
||||
"//media:media_buildflags",
|
||||
"//media/gpu",
|
||||
"//media/mojo:buildflags",
|
||||
|
||||
# TODO(jrummell): As //media/gpu/ipc/service is a source_set in a
|
||||
# component build, determine if it should not be included here.
|
||||
# http://crbug.com/702833.
|
||||
"//components/viz/service/main",
|
||||
"//media/gpu/ipc/service",
|
||||
"//media/mojo/clients:clients",
|
||||
"//sandbox/policy:chromecast_sandbox_allowlist_buildflags",
|
||||
"//services/service_manager/public/cpp",
|
||||
"//services/service_manager/public/mojom",
|
||||
"//services/tracing/public/cpp",
|
||||
"//services/viz/privileged/mojom",
|
||||
"//skia",
|
||||
"//third_party/angle:angle_gpu_info_util",
|
||||
"//ui/gfx/ipc",
|
||||
"//ui/gl",
|
||||
"//ui/gl/init",
|
||||
"//ui/latency/ipc",
|
||||
]
|
||||
|
||||
if (!is_chromeos_ash || !is_chrome_branded) {
|
||||
deps += [
|
||||
"//services/shape_detection:lib",
|
||||
"//services/shape_detection/public/mojom",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_linux || is_chromeos) {
|
||||
sources += [
|
||||
"gpu_sandbox_hook_linux.cc",
|
||||
"gpu_sandbox_hook_linux.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_chromeos_ash) {
|
||||
deps += [
|
||||
"//components/services/font/public/cpp",
|
||||
"//components/services/font/public/mojom",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
deps += [
|
||||
"//components/tracing:graphics_provider",
|
||||
"//media",
|
||||
]
|
||||
}
|
||||
|
||||
if (mojo_media_host == "gpu") {
|
||||
deps += [ "//media/mojo/services" ]
|
||||
}
|
||||
|
||||
if (is_linux || is_chromeos || is_mac || is_win) {
|
||||
deps += [ "//sandbox" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
deps += [ "//components/metal_util" ]
|
||||
}
|
||||
|
||||
if (use_ozone) {
|
||||
deps += [ "//ui/ozone" ]
|
||||
}
|
||||
|
||||
if (enable_vulkan) {
|
||||
deps += [ "//gpu/vulkan" ]
|
||||
}
|
||||
|
||||
# Use DRI on desktop Linux builds.
|
||||
if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux &&
|
||||
!is_castos) {
|
||||
configs += [ "//build/config/linux/dri" ]
|
||||
}
|
||||
|
||||
if (is_linux && use_vaapi) {
|
||||
public_configs = [ "//build/config/linux/libva" ]
|
||||
}
|
||||
}
|
910
src/content/shell/BUILD.gn
Normal file
910
src/content/shell/BUILD.gn
Normal file
|
@ -0,0 +1,910 @@
|
|||
# Copyright 2022 The Chromium Authors and Alex313031. 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/chromeos/ui_mode.gni")
|
||||
import("//build/config/features.gni")
|
||||
import("//build/config/ozone.gni")
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//build/config/win/console_app.gni")
|
||||
import("//build/config/win/manifest.gni")
|
||||
import("//gpu/vulkan/features.gni")
|
||||
import("//media/media_options.gni")
|
||||
import("//mojo/public/tools/bindings/mojom.gni")
|
||||
import("//ppapi/buildflags/buildflags.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
import("//tools/grit/repack.gni")
|
||||
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
|
||||
if (is_android) {
|
||||
import("//build/config/android/config.gni")
|
||||
} else if (is_mac) {
|
||||
import("//build/apple/tweak_info_plist.gni")
|
||||
import("//build/config/mac/rules.gni")
|
||||
import("//content/public/app/mac_helpers.gni")
|
||||
import("//third_party/icu/config.gni")
|
||||
import("//ui/gl/features.gni")
|
||||
import("//v8/gni/v8.gni")
|
||||
}
|
||||
|
||||
# TODO(crbug.com/1336055, spang): Investigate using shell_views with cast builds as
|
||||
# true.
|
||||
shell_use_toolkit_views = toolkit_views && !is_castos
|
||||
|
||||
declare_args() {
|
||||
content_shell_product_name = "Thorium Shell"
|
||||
content_shell_version = "999.77.34.5"
|
||||
content_shell_major_version = "999"
|
||||
}
|
||||
|
||||
config("content_shell_lib_warnings") {
|
||||
if (is_clang) {
|
||||
# TODO(thakis): Remove this once http://crbug.com/383820 is figured out
|
||||
cflags = [ "-Wno-nonnull" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Web test support not built on android, but is everywhere else.
|
||||
support_web_tests = !is_android
|
||||
|
||||
source_set("android_shell_descriptors") {
|
||||
testonly = true
|
||||
sources = []
|
||||
public_deps = [ "//content/public/common:content_descriptors" ]
|
||||
if (is_android) {
|
||||
sources += [ "android/shell_descriptors.h" ]
|
||||
}
|
||||
}
|
||||
|
||||
# This component provides a ContentMainDelegate for Content Shell and derived
|
||||
# applications. This delegate is the central place that creates interfaces for
|
||||
# each type of process (browser, renderer, etc). This implementation of
|
||||
# ContentMainDelegate will create either production or test-based
|
||||
# implementations.
|
||||
#
|
||||
# This component needs to be linked into every process in a Content Shell-based
|
||||
# application that wants to use ShellMainDelegate.
|
||||
#
|
||||
# TODO(danakj): This component will depend on {renderer,browser}/web_test. The
|
||||
# content_shell_lib component will not, to avoid circular deps, as web_test
|
||||
# inherits from things in content_shell_lib.
|
||||
static_library("content_shell_app") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"app/shell_crash_reporter_client.cc",
|
||||
"app/shell_crash_reporter_client.h",
|
||||
"app/shell_main_delegate.cc",
|
||||
"app/shell_main_delegate.h",
|
||||
]
|
||||
deps = [
|
||||
":content_shell_lib",
|
||||
"//components/crash/core/common:crash_key",
|
||||
"//content/public/app",
|
||||
"//v8",
|
||||
]
|
||||
if (support_web_tests) {
|
||||
deps += [
|
||||
"//content/web_test:web_test_browser",
|
||||
"//content/web_test:web_test_common",
|
||||
"//content/web_test:web_test_renderer",
|
||||
]
|
||||
}
|
||||
if (!is_fuchsia) {
|
||||
deps += [
|
||||
"//components/crash/core/app",
|
||||
"//components/crash/core/app:test_support",
|
||||
]
|
||||
}
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"app/paths_mac.h",
|
||||
"app/paths_mac.mm",
|
||||
"app/shell_main_delegate_mac.h",
|
||||
"app/shell_main_delegate_mac.mm",
|
||||
]
|
||||
}
|
||||
defines = [
|
||||
"CONTENT_SHELL_VERSION=\"$content_shell_version\"",
|
||||
"CONTENT_SHELL_MAJOR_VERSION=\"$content_shell_major_version\"",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("content_shell_lib") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"browser/shell.cc",
|
||||
"browser/shell.h",
|
||||
"browser/shell_browser_context.cc",
|
||||
"browser/shell_browser_context.h",
|
||||
"browser/shell_browser_main_parts.cc",
|
||||
"browser/shell_browser_main_parts.h",
|
||||
"browser/shell_content_browser_client.cc",
|
||||
"browser/shell_content_browser_client.h",
|
||||
"browser/shell_content_index_provider.cc",
|
||||
"browser/shell_content_index_provider.h",
|
||||
"browser/shell_devtools_bindings.cc",
|
||||
"browser/shell_devtools_bindings.h",
|
||||
"browser/shell_devtools_frontend.cc",
|
||||
"browser/shell_devtools_frontend.h",
|
||||
"browser/shell_devtools_manager_delegate.cc",
|
||||
"browser/shell_devtools_manager_delegate.h",
|
||||
"browser/shell_download_manager_delegate.cc",
|
||||
"browser/shell_download_manager_delegate.h",
|
||||
"browser/shell_federated_permission_context.cc",
|
||||
"browser/shell_federated_permission_context.h",
|
||||
"browser/shell_javascript_dialog.h",
|
||||
"browser/shell_javascript_dialog_manager.cc",
|
||||
"browser/shell_javascript_dialog_manager.h",
|
||||
"browser/shell_paths.cc",
|
||||
"browser/shell_paths.h",
|
||||
"browser/shell_permission_manager.cc",
|
||||
"browser/shell_permission_manager.h",
|
||||
"browser/shell_platform_data_aura.cc",
|
||||
"browser/shell_platform_data_aura.h",
|
||||
"browser/shell_platform_delegate.cc",
|
||||
"browser/shell_platform_delegate.h",
|
||||
"browser/shell_quota_permission_context.cc",
|
||||
"browser/shell_quota_permission_context.h",
|
||||
"browser/shell_speech_recognition_manager_delegate.cc",
|
||||
"browser/shell_speech_recognition_manager_delegate.h",
|
||||
"browser/shell_web_contents_view_delegate.h",
|
||||
"browser/shell_web_contents_view_delegate_creator.h",
|
||||
"common/power_monitor_test_impl.cc",
|
||||
"common/power_monitor_test_impl.h",
|
||||
"common/shell_content_client.cc",
|
||||
"common/shell_content_client.h",
|
||||
"common/shell_origin_trial_policy.cc",
|
||||
"common/shell_origin_trial_policy.h",
|
||||
"common/shell_switches.cc",
|
||||
"common/shell_switches.h",
|
||||
"gpu/shell_content_gpu_client.cc",
|
||||
"gpu/shell_content_gpu_client.h",
|
||||
"renderer/shell_content_renderer_client.cc",
|
||||
"renderer/shell_content_renderer_client.h",
|
||||
"renderer/shell_render_frame_observer.cc",
|
||||
"renderer/shell_render_frame_observer.h",
|
||||
"utility/shell_content_utility_client.cc",
|
||||
"utility/shell_content_utility_client.h",
|
||||
]
|
||||
|
||||
if (is_android) {
|
||||
sources += [
|
||||
"android/shell_manager.cc",
|
||||
"android/shell_manager.h",
|
||||
"browser/shell_platform_delegate_android.cc",
|
||||
"browser/shell_web_contents_view_delegate_android.cc",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"browser/renderer_host/shell_render_widget_host_view_mac_delegate.h",
|
||||
"browser/renderer_host/shell_render_widget_host_view_mac_delegate.mm",
|
||||
"browser/shell_application_mac.h",
|
||||
"browser/shell_application_mac.mm",
|
||||
"browser/shell_browser_main_parts_mac.mm",
|
||||
"browser/shell_javascript_dialog_mac.mm",
|
||||
"browser/shell_platform_delegate_mac.mm",
|
||||
"browser/shell_web_contents_view_delegate_mac.mm",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += [ "browser/shell_javascript_dialog_win.cc" ]
|
||||
}
|
||||
|
||||
configs += [
|
||||
":content_shell_lib_warnings",
|
||||
"//build/config:precompiled_headers",
|
||||
]
|
||||
|
||||
defines = [
|
||||
"CONTENT_SHELL_VERSION=\"$content_shell_version\"",
|
||||
"CONTENT_SHELL_MAJOR_VERSION=\"$content_shell_major_version\"",
|
||||
]
|
||||
|
||||
# This is to support our dependency on //content/browser.
|
||||
# See comment at the top of //content/BUILD.gn for why this is disabled in
|
||||
# component builds.
|
||||
if (is_component_build) {
|
||||
check_includes = false
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
":android_shell_descriptors",
|
||||
|
||||
# content_shell_lib also exposes all public content APIs.
|
||||
"//content/public/app",
|
||||
"//content/public/browser",
|
||||
"//content/public/child",
|
||||
"//content/public/common",
|
||||
"//content/public/gpu",
|
||||
"//content/public/renderer",
|
||||
"//content/public/utility",
|
||||
"//services/network:network_service",
|
||||
]
|
||||
deps = [
|
||||
":content_browsertests_mojom",
|
||||
":resources",
|
||||
":shell_controller_mojom",
|
||||
"//base",
|
||||
"//base:base_static",
|
||||
"//base/third_party/dynamic_annotations",
|
||||
"//build:chromeos_buildflags",
|
||||
"//cc/base",
|
||||
"//components/cdm/renderer",
|
||||
"//components/custom_handlers",
|
||||
"//components/custom_handlers:test_support",
|
||||
"//components/keyed_service/content",
|
||||
"//components/metrics",
|
||||
"//components/metrics:net",
|
||||
"//components/metrics:test_support",
|
||||
"//components/network_session_configurator/common",
|
||||
"//components/performance_manager",
|
||||
"//components/permissions",
|
||||
"//components/prefs",
|
||||
"//components/services/storage/test_api",
|
||||
"//components/url_formatter",
|
||||
"//components/variations",
|
||||
"//components/variations/service",
|
||||
"//components/web_cache/renderer",
|
||||
"//content:content_resources",
|
||||
"//content:dev_ui_content_resources",
|
||||
"//content/public/common",
|
||||
"//content/test:content_test_mojo_bindings",
|
||||
"//content/test:test_support",
|
||||
"//device/bluetooth",
|
||||
"//media",
|
||||
"//media/mojo:buildflags",
|
||||
"//net",
|
||||
"//net:net_resources",
|
||||
"//ppapi/buildflags",
|
||||
"//services/device/public/cpp:test_support",
|
||||
"//services/network/public/cpp",
|
||||
"//services/test/echo:lib",
|
||||
"//services/test/echo/public/mojom",
|
||||
"//third_party/blink/public:blink",
|
||||
"//third_party/blink/public:image_resources",
|
||||
"//third_party/blink/public:resources",
|
||||
"//third_party/blink/public/strings",
|
||||
"//third_party/blink/public/strings:accessibility_strings",
|
||||
"//ui/base",
|
||||
"//ui/base/clipboard",
|
||||
"//ui/base/ime/init",
|
||||
"//ui/gfx",
|
||||
"//ui/gfx/geometry",
|
||||
"//ui/platform_window",
|
||||
"//url",
|
||||
"//v8",
|
||||
]
|
||||
|
||||
if (is_fuchsia) {
|
||||
deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy" ]
|
||||
} else {
|
||||
deps += [
|
||||
"//components/crash/content/browser",
|
||||
"//components/crash/core/app",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_plugins) {
|
||||
sources += [
|
||||
"browser/shell_plugin_service_filter.cc",
|
||||
"browser/shell_plugin_service_filter.h",
|
||||
]
|
||||
deps += [ "//ppapi/shared_impl" ]
|
||||
}
|
||||
if (enable_cast_renderer) {
|
||||
deps += [ "//media/mojo/services" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
"common/v8_crashpad_support_win.cc",
|
||||
"common/v8_crashpad_support_win.h",
|
||||
]
|
||||
deps += [ "//gin" ]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
deps += [ "//ui/views/linux_ui:linux_ui_factory" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
deps += [ "//ui/display:test_support" ]
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
deps += [
|
||||
"//components/embedder_support/android:view",
|
||||
"//content/shell/android:content_shell_jni_headers",
|
||||
"//mojo/public/java/system:test_support",
|
||||
"//ui/android",
|
||||
]
|
||||
}
|
||||
|
||||
if (shell_use_toolkit_views) {
|
||||
# All content_shell code should use this define instead of TOOLKIT_VIEWS,
|
||||
# since any transitive dependency on //ui/views from another component will
|
||||
# cause TOOLKIT_VIEWS to be defined, even when content_shell does not want
|
||||
# to use it internally. See https://crbug.com/1218907.
|
||||
defines += [ "SHELL_USE_TOOLKIT_VIEWS=1" ]
|
||||
deps += [ "//ui/views" ]
|
||||
}
|
||||
|
||||
if (use_aura) {
|
||||
deps += [
|
||||
"//ui/aura",
|
||||
"//ui/aura:test_support",
|
||||
"//ui/events",
|
||||
"//ui/wm",
|
||||
]
|
||||
|
||||
if (shell_use_toolkit_views) {
|
||||
sources += [
|
||||
"browser/shell_platform_delegate_views.cc",
|
||||
"browser/shell_web_contents_view_delegate_views.cc",
|
||||
]
|
||||
deps += [
|
||||
"//ui/color:color_headers",
|
||||
"//ui/native_theme",
|
||||
"//ui/resources",
|
||||
"//ui/views:test_support",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/wm:test_support",
|
||||
]
|
||||
} else {
|
||||
sources += [
|
||||
"browser/shell_platform_delegate_aura.cc",
|
||||
"browser/shell_web_contents_view_delegate_aura.cc",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
sources -= [
|
||||
"browser/shell_platform_data_aura.cc",
|
||||
"browser/shell_platform_data_aura.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_chromeos_ash) {
|
||||
deps += [ "//chromeos/dbus" ]
|
||||
}
|
||||
|
||||
if (is_chromeos_lacros) {
|
||||
deps += [
|
||||
"//chromeos/dbus/constants",
|
||||
"//chromeos/lacros/dbus",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_linux || is_chromeos) {
|
||||
deps += [ "//build/config/freetype" ]
|
||||
}
|
||||
|
||||
if (use_ozone) {
|
||||
deps += [ "//ui/ozone" ]
|
||||
}
|
||||
}
|
||||
|
||||
grit("content_shell_resources_grit") {
|
||||
testonly = true
|
||||
|
||||
# External code should depend on ":resources" instead.
|
||||
visibility = [ ":*" ]
|
||||
source = "shell_resources.grd"
|
||||
outputs = [
|
||||
"grit/shell_resources.h",
|
||||
"shell_resources.pak",
|
||||
]
|
||||
}
|
||||
|
||||
copy("copy_shell_resources") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "$target_gen_dir/shell_resources.pak" ]
|
||||
outputs = [ "$root_out_dir/shell_resources.pak" ]
|
||||
|
||||
public_deps = [ ":content_shell_resources_grit" ]
|
||||
}
|
||||
|
||||
group("resources") {
|
||||
testonly = true
|
||||
|
||||
public_deps = [ ":copy_shell_resources" ]
|
||||
}
|
||||
|
||||
repack("pak") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"$root_gen_dir/base/tracing/protos/tracing_proto_resources.pak",
|
||||
"$root_gen_dir/content/browser/resources/media/media_internals_resources.pak",
|
||||
"$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
|
||||
"$root_gen_dir/content/content_resources.pak",
|
||||
"$root_gen_dir/content/dev_ui_content_resources.pak",
|
||||
"$root_gen_dir/content/quota_internals_resources.pak",
|
||||
"$root_gen_dir/content/shell/shell_resources.pak",
|
||||
"$root_gen_dir/content/test/web_ui_mojo_test_resources.pak",
|
||||
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
|
||||
"$root_gen_dir/net/net_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/strings/blink_accessibility_strings_en-US.pak",
|
||||
"$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
|
||||
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
|
||||
"$root_gen_dir/ui/resources/webui_generated_resources.pak",
|
||||
"$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
|
||||
"$root_gen_dir/ui/strings/ax_strings_en-US.pak",
|
||||
"$root_gen_dir/ui/strings/ui_strings_en-US.pak",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":resources",
|
||||
"//base/tracing/protos:chrome_track_event_resources",
|
||||
"//content:content_resources",
|
||||
"//content:dev_ui_content_resources",
|
||||
"//content/browser/resources:resources",
|
||||
"//content/browser/resources/media:resources",
|
||||
"//content/browser/webrtc/resources",
|
||||
"//content/test:web_ui_mojo_test_resources",
|
||||
"//mojo/public/js:resources",
|
||||
"//net:net_resources",
|
||||
"//third_party/blink/public:devtools_inspector_resources",
|
||||
"//third_party/blink/public:resources",
|
||||
"//third_party/blink/public:scaled_resources_100_percent",
|
||||
"//third_party/blink/public/strings",
|
||||
"//third_party/blink/public/strings:accessibility_strings",
|
||||
"//ui/resources",
|
||||
"//ui/strings",
|
||||
]
|
||||
|
||||
if (!is_android) {
|
||||
deps += [ "//content/browser/tracing:resources" ]
|
||||
sources += [ "$root_gen_dir/content/browser/tracing/tracing_resources.pak" ]
|
||||
}
|
||||
|
||||
if (shell_use_toolkit_views) {
|
||||
deps += [ "//ui/views/resources" ]
|
||||
sources +=
|
||||
[ "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak" ]
|
||||
}
|
||||
if (!is_android && !is_fuchsia) {
|
||||
sources +=
|
||||
[ "$root_gen_dir/content/browser/devtools/devtools_resources.pak" ]
|
||||
deps += [ "//content/browser/devtools:devtools_resources" ]
|
||||
}
|
||||
output = "$root_out_dir/content_shell.pak"
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
group("content_shell") {
|
||||
testonly = true
|
||||
deps = [ "//content/shell/android:content_shell_apk" ]
|
||||
}
|
||||
} else if (is_mac) {
|
||||
tweak_info_plist("content_shell_plist") {
|
||||
testonly = true
|
||||
info_plist = "app/app-Info.plist"
|
||||
args = [
|
||||
"--scm=1",
|
||||
"--version",
|
||||
content_shell_version,
|
||||
]
|
||||
}
|
||||
mac_app_bundle("content_shell") {
|
||||
testonly = true
|
||||
output_name = content_shell_product_name
|
||||
sources = [ "app/shell_main_mac.cc" ]
|
||||
defines = [ "SHELL_PRODUCT_NAME=\"$content_shell_product_name\"" ]
|
||||
|
||||
# Must have minimal dependencies. In particular cannot depend on //base.
|
||||
# Depending on //base leads to loading //base twice (once in the exe, once
|
||||
# in the main framework).
|
||||
deps = [
|
||||
":content_shell_framework_bundle_data",
|
||||
":content_shell_resources_bundle_data",
|
||||
|
||||
# Despite its path, this does not add a //base dependency, see comments in
|
||||
# the .cc file.
|
||||
"//base/allocator:early_zone_registration_mac",
|
||||
"//sandbox/mac:seatbelt",
|
||||
]
|
||||
info_plist_target = ":content_shell_plist"
|
||||
data_deps = [ ":content_shell_app" ]
|
||||
|
||||
if (is_component_build) {
|
||||
ldflags = [ "-Wl,-rpath,@executable_path/../Frameworks" ]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
executable("thorium_shell") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "app/shell_main.cc" ]
|
||||
|
||||
if (is_win) {
|
||||
sources += [ "app/shell.rc" ]
|
||||
}
|
||||
|
||||
defines = []
|
||||
|
||||
deps = [
|
||||
":content_shell_app",
|
||||
":pak",
|
||||
"//build/win:default_exe_manifest",
|
||||
"//content/public/app",
|
||||
"//sandbox",
|
||||
]
|
||||
|
||||
data_deps = [
|
||||
":pak",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
deps += [
|
||||
"//base",
|
||||
"//sandbox",
|
||||
]
|
||||
if (win_console_app) {
|
||||
defines += [ "WIN_CONSOLE_APP" ]
|
||||
} else {
|
||||
# Set /SUBSYSTEM:WINDOWS unless a console build has been requested.
|
||||
configs -= [ "//build/config/win:console" ]
|
||||
configs += [ "//build/config/win:windowed" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
data_deps +=
|
||||
[ "//third_party/crashpad/crashpad/handler:crashpad_handler" ]
|
||||
} else if (is_linux || is_chromeos) {
|
||||
data_deps += [ "//components/crash/core/app:chrome_crashpad_handler" ]
|
||||
}
|
||||
|
||||
if ((is_linux || is_chromeos) && !is_component_build) {
|
||||
# Set rpath to find our own libfreetype even in a non-component build.
|
||||
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_fuchsia) {
|
||||
fuchsia_component("content_shell_component") {
|
||||
testonly = true
|
||||
manifest = "fuchsia/content_shell.cmx"
|
||||
data_deps = [ ":thorium_shell" ]
|
||||
visibility = [ ":*" ]
|
||||
}
|
||||
|
||||
fuchsia_package("content_shell_pkg") {
|
||||
testonly = true
|
||||
package_name = "thorium_shell"
|
||||
deps = [ ":content_shell_component" ]
|
||||
}
|
||||
|
||||
fuchsia_package_installer("content_shell_fuchsia") {
|
||||
testonly = true
|
||||
visibility = [
|
||||
":*", # See https://crbug.com/1328459#c4.
|
||||
"//:*",
|
||||
]
|
||||
package = ":content_shell_pkg"
|
||||
package_name = "thorium_shell"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
bundle_data("content_shell_framework_resources") {
|
||||
testonly = true
|
||||
sources = [ "$root_out_dir/content_shell.pak" ]
|
||||
|
||||
public_deps = [ ":pak" ]
|
||||
|
||||
if (icu_use_data_file) {
|
||||
sources += [ "$root_out_dir/icudtl.dat" ]
|
||||
deps = [ "//third_party/icu:icudata" ]
|
||||
}
|
||||
|
||||
if (v8_use_external_startup_data) {
|
||||
public_deps += [ "//v8" ]
|
||||
if (use_v8_context_snapshot) {
|
||||
sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
|
||||
public_deps += [ "//tools/v8_context_snapshot" ]
|
||||
} else {
|
||||
sources += [ "$root_out_dir/snapshot_blob.bin" ]
|
||||
}
|
||||
}
|
||||
|
||||
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
if (enable_plugins) {
|
||||
bundle_data("content_shell_framework_plugins") {
|
||||
sources = [
|
||||
"$root_out_dir/blink_deprecated_test_plugin.plugin",
|
||||
"$root_out_dir/blink_test_plugin.plugin",
|
||||
]
|
||||
|
||||
outputs = [ "{{bundle_contents_dir}}/{{source_file_part}}" ]
|
||||
|
||||
public_deps = [
|
||||
"//ppapi:blink_deprecated_test_plugin",
|
||||
"//ppapi:blink_test_plugin",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
content_shell_framework_name = "$content_shell_product_name Framework"
|
||||
content_shell_helper_name = "$content_shell_product_name Helper"
|
||||
|
||||
bundle_data("content_shell_framework_helpers") {
|
||||
testonly = true
|
||||
sources = [ "$root_out_dir/chrome_crashpad_handler" ]
|
||||
outputs = [ "{{bundle_contents_dir}}/Helpers/{{source_file_part}}" ]
|
||||
public_deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
sources += [
|
||||
"$root_out_dir/${content_shell_helper_name}${helper_params[2]}.app",
|
||||
]
|
||||
public_deps += [ ":content_shell_helper_app_${helper_params[0]}" ]
|
||||
}
|
||||
}
|
||||
|
||||
tweak_info_plist("content_shell_framework_plist") {
|
||||
testonly = true
|
||||
info_plist = "app/framework-Info.plist"
|
||||
args = [
|
||||
"--breakpad=0",
|
||||
"--keystone=0",
|
||||
"--scm=1",
|
||||
"--version",
|
||||
content_shell_version,
|
||||
"--branding",
|
||||
content_shell_product_name,
|
||||
]
|
||||
}
|
||||
|
||||
mac_framework_bundle("content_shell_framework") {
|
||||
testonly = true
|
||||
|
||||
output_name = content_shell_framework_name
|
||||
|
||||
framework_version = "C"
|
||||
|
||||
framework_contents = [
|
||||
"Helpers",
|
||||
"Libraries",
|
||||
"Resources",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"app/shell_content_main.cc",
|
||||
"app/shell_content_main.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":content_shell_angle_library",
|
||||
":content_shell_app",
|
||||
"//content/public/app",
|
||||
"//content/public/common",
|
||||
"//third_party/icu:icudata",
|
||||
]
|
||||
|
||||
bundle_deps = [
|
||||
":content_shell_framework_helpers",
|
||||
":content_shell_framework_resources",
|
||||
":content_shell_swiftshader_library",
|
||||
]
|
||||
|
||||
if (enable_plugins) {
|
||||
deps += [ ":content_shell_framework_plugins" ]
|
||||
}
|
||||
|
||||
if (!is_component_build) {
|
||||
# Specify a sensible install_name for static builds. The library is
|
||||
# dlopen()ed so this is not used to resolve the module.
|
||||
ldflags = [ "-Wl,-install_name,@executable_path/../Frameworks/$output_name.framework/$output_name" ]
|
||||
} else {
|
||||
# Both the main :content_shell and :content_shell_helper_app executables
|
||||
# need to link the framework. Because they are at different directory
|
||||
# depths, using @executable_path as the install_name would require using
|
||||
# install_name_tool on one of the executables. However install_name_tool
|
||||
# only operates in-place, which is problematic to express in GN. Instead,
|
||||
# use rpath-based loading.
|
||||
ldflags =
|
||||
[ "-Wl,-install_name,@rpath/$output_name.framework/$output_name" ]
|
||||
|
||||
# Set up the rpath for the framework so that it can find dylibs in the
|
||||
# root output directory. The framework is at
|
||||
# Content Shell.app/Contents/Frameworks/Content Shell Framework.framework/Versions/C/Content Shell Framework
|
||||
# so use loader_path to go back to the root output directory.
|
||||
ldflags += [ "-Wl,-rpath,@loader_path/../../../../../.." ]
|
||||
}
|
||||
|
||||
info_plist_target = ":content_shell_framework_plist"
|
||||
}
|
||||
|
||||
tweak_info_plist("content_shell_helper_plist") {
|
||||
testonly = true
|
||||
info_plist = "app/helper-Info.plist"
|
||||
args = [
|
||||
"--breakpad=0",
|
||||
"--keystone=0",
|
||||
"--scm=0",
|
||||
"--version",
|
||||
content_shell_version,
|
||||
]
|
||||
}
|
||||
|
||||
template("content_shell_helper_app") {
|
||||
mac_app_bundle(target_name) {
|
||||
assert(defined(invoker.helper_name_suffix))
|
||||
assert(defined(invoker.helper_bundle_id_suffix))
|
||||
|
||||
testonly = true
|
||||
|
||||
output_name = content_shell_helper_name + invoker.helper_name_suffix
|
||||
|
||||
sources = [ "app/shell_main_mac.cc" ]
|
||||
defines = [
|
||||
"HELPER_EXECUTABLE",
|
||||
"SHELL_PRODUCT_NAME=\"$content_shell_product_name\"",
|
||||
]
|
||||
extra_substitutions = [
|
||||
"CONTENT_SHELL_HELPER_SUFFIX=${invoker.helper_name_suffix}",
|
||||
"CONTENT_SHELL_HELPER_BUNDLE_ID_SUFFIX=${invoker.helper_bundle_id_suffix}",
|
||||
]
|
||||
deps = [
|
||||
"//base/allocator:early_zone_registration_mac",
|
||||
"//sandbox/mac:seatbelt",
|
||||
]
|
||||
|
||||
info_plist_target = ":content_shell_helper_plist"
|
||||
|
||||
if (is_component_build) {
|
||||
ldflags = [
|
||||
# The helper is in Content Shell.app/Contents/Frameworks/
|
||||
# Content Shell Framework.framework/Versions/C/Helpers/
|
||||
# Content Shell Helper.app/Contents/MacOS/
|
||||
# so set rpath up to the base.
|
||||
"-Wl,-rpath,@executable_path/../../../../../../../../../..",
|
||||
|
||||
# ... and up to Contents/Frameworks.
|
||||
"-Wl,-rpath,@executable_path/../../../../../../..",
|
||||
]
|
||||
|
||||
# In a component build, the framework is directly linked to the
|
||||
# executable because dlopen() and loading all the dependent dylibs
|
||||
# is time-consuming, see https://crbug.com/1197495.
|
||||
deps += [ ":content_shell_framework+link_nested" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
_helper_target = helper_params[0]
|
||||
_helper_bundle_id = helper_params[1]
|
||||
_helper_suffix = helper_params[2]
|
||||
content_shell_helper_app("content_shell_helper_app_${_helper_target}") {
|
||||
helper_name_suffix = _helper_suffix
|
||||
helper_bundle_id_suffix = _helper_bundle_id
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("content_shell_framework_bundle_data") {
|
||||
testonly = true
|
||||
sources = [ "$root_out_dir/$content_shell_framework_name.framework" ]
|
||||
outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
|
||||
if (is_component_build) {
|
||||
# In a component build, the framework is directly linked to the
|
||||
# executable because dlopen() and loading all the dependent dylibs
|
||||
# is time-consuming, see https://crbug.com/1197495.
|
||||
public_deps = [ ":content_shell_framework+link" ]
|
||||
} else {
|
||||
public_deps = [ ":content_shell_framework" ]
|
||||
}
|
||||
}
|
||||
|
||||
bundle_data("content_shell_resources_bundle_data") {
|
||||
testonly = true
|
||||
sources = [ "app/app.icns" ]
|
||||
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
if (use_egl) {
|
||||
# Add the ANGLE .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("content_shell_angle_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/egl_intermediates/libEGL.dylib",
|
||||
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
|
||||
]
|
||||
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
|
||||
public_deps = [ "//ui/gl:angle_library_copy" ]
|
||||
}
|
||||
|
||||
# Add the SwiftShader .dylibs in the Libraries directory of the Framework.
|
||||
bundle_data("content_shell_swiftshader_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/vk_intermediates/libvk_swiftshader.dylib",
|
||||
"$root_out_dir/vk_intermediates/vk_swiftshader_icd.json",
|
||||
]
|
||||
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
|
||||
public_deps = [ "//ui/gl:swiftshader_vk_library_copy" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("content_shell_angle_library") {
|
||||
if (use_egl) {
|
||||
deps = [ ":content_shell_angle_binaries" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("content_shell_swiftshader_library") {
|
||||
if (use_egl) {
|
||||
deps = [ ":content_shell_swiftshader_binaries" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mojom("content_browsertests_mojom") {
|
||||
sources = [ "common/power_monitor_test.mojom" ]
|
||||
public_deps = [ "//sandbox/policy/mojom" ]
|
||||
}
|
||||
|
||||
group("content_shell_crash_test") {
|
||||
testonly = true
|
||||
data_deps = [
|
||||
":thorium_shell",
|
||||
"//testing:test_scripts_shared",
|
||||
"//third_party/mesa_headers",
|
||||
]
|
||||
data = [
|
||||
"//content/shell/tools/breakpad_integration_test.py",
|
||||
"//testing/scripts/content_shell_crash_test.py",
|
||||
]
|
||||
if (is_mac && !use_system_xcode) {
|
||||
data += [
|
||||
# Scripts call otool, which calls either llvm-otool or otool-classic,
|
||||
# so we need all three.
|
||||
# llvm-otool shells out to llvm-objdump, so that's needed as well.
|
||||
mac_bin_path + "llvm-objdump",
|
||||
mac_bin_path + "llvm-otool",
|
||||
mac_bin_path + "otool",
|
||||
mac_bin_path + "otool-classic",
|
||||
]
|
||||
}
|
||||
if (is_posix) {
|
||||
data += [
|
||||
"//components/crash/content/tools/generate_breakpad_symbols.py",
|
||||
"//components/crash/content/tools/dmp2minidump.py",
|
||||
]
|
||||
}
|
||||
if (is_win) {
|
||||
data_deps += [ "//build/win:copy_cdb_to_output" ]
|
||||
}
|
||||
if (is_posix) {
|
||||
data_deps += [
|
||||
"//third_party/breakpad:dump_syms",
|
||||
"//third_party/breakpad:minidump_stackwalk",
|
||||
]
|
||||
}
|
||||
if (is_android) {
|
||||
data_deps += [
|
||||
"//build/android:devil_chromium_py",
|
||||
"//build/android:test_runner_py",
|
||||
"//third_party/breakpad:microdump_stackwalk",
|
||||
"//third_party/breakpad:minidump_dump",
|
||||
"//third_party/breakpad:symupload",
|
||||
"//tools/android/forwarder2",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
mojom("shell_controller_mojom") {
|
||||
testonly = true
|
||||
sources = [ "common/shell_controller.test-mojom" ]
|
||||
public_deps = [ "//mojo/public/mojom/base" ]
|
||||
}
|
149
src/content/shell/app/shell.rc
Normal file
149
src/content/shell/app/shell.rc
Normal file
|
@ -0,0 +1,149 @@
|
|||
//Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "content/shell/app/resource.h"
|
||||
#include "build/branding_buildflags.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE 9, 1
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDC_CONTENTSHELL MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&New Window", IDM_NEW_WINDOW
|
||||
MENUITEM "&Close Window", IDM_CLOSE_WINDOW
|
||||
MENUITEM "E&xit", IDM_EXIT
|
||||
END
|
||||
POPUP "&Debug"
|
||||
BEGIN
|
||||
MENUITEM "&Show Developer Tools...", IDM_SHOW_DEVELOPER_TOOLS
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ALERT DIALOGEX 0, 0, 241, 76
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Alert"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,184,55,50,14
|
||||
LTEXT "",IDC_DIALOGTEXT,16,17,210,30
|
||||
END
|
||||
|
||||
IDD_CONFIRM DIALOGEX 0, 0, 241, 76
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Confirm"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,131,55,50,14
|
||||
LTEXT "",IDC_DIALOGTEXT,16,17,210,30
|
||||
END
|
||||
|
||||
IDD_PROMPT DIALOGEX 0, 0, 241, 76
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Prompt"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,131,55,50,14
|
||||
LTEXT "",IDC_DIALOGTEXT,16,17,210,18
|
||||
PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14
|
||||
EDITTEXT IDC_PROMPTEDIT,15,33,210,14,ES_AUTOHSCROLL
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_ALERT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 234
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 69
|
||||
END
|
||||
|
||||
IDD_CONFIRM, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 234
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 69
|
||||
END
|
||||
|
||||
IDD_PROMPT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 234
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 69
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
1 ICON "thorium_shell.ico"
|
384
src/content/shell/app/shell_main_delegate.cc
Normal file
384
src/content/shell/app/shell_main_delegate.cc
Normal file
|
@ -0,0 +1,384 @@
|
|||
// Copyright (c) 2022 The Chromium Authors and Alex313031. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "content/shell/app/shell_main_delegate.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "base/base_paths.h"
|
||||
#include "base/base_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/cpu.h"
|
||||
#include "base/files/file.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/trace_event/trace_log.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/crash/core/common/crash_key.h"
|
||||
#include "content/common/content_constants_internal.h"
|
||||
#include "content/public/browser/browser_main_runner.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/shell/app/shell_crash_reporter_client.h"
|
||||
#include "content/shell/browser/shell_content_browser_client.h"
|
||||
#include "content/shell/browser/shell_paths.h"
|
||||
#include "content/shell/common/shell_content_client.h"
|
||||
#include "content/shell/common/shell_switches.h"
|
||||
#include "content/shell/gpu/shell_content_gpu_client.h"
|
||||
#include "content/shell/renderer/shell_content_renderer_client.h"
|
||||
#include "content/shell/utility/shell_content_utility_client.h"
|
||||
#include "ipc/ipc_buildflags.h"
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
#include "third_party/abseil-cpp/absl/types/variant.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
|
||||
#define IPC_MESSAGE_MACROS_LOG_ENABLED
|
||||
#include "content/public/common/content_ipc_logging.h"
|
||||
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
|
||||
content::RegisterIPCLogger(msg_id, logger)
|
||||
#endif
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
#include "content/web_test/browser/web_test_browser_main_runner.h" // nogncheck
|
||||
#include "content/web_test/browser/web_test_content_browser_client.h" // nogncheck
|
||||
#include "content/web_test/renderer/web_test_content_renderer_client.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
#include "base/android/apk_assets.h"
|
||||
#include "base/posix/global_descriptors.h"
|
||||
#include "content/public/browser/android/compositor.h"
|
||||
#include "content/shell/android/shell_descriptors.h"
|
||||
#endif
|
||||
|
||||
#if !BUILDFLAG(IS_FUCHSIA)
|
||||
#include "components/crash/core/app/crashpad.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "content/shell/app/paths_mac.h"
|
||||
#include "content/shell/app/shell_main_delegate_mac.h"
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include <windows.h>
|
||||
|
||||
#include <initguid.h>
|
||||
#include "base/logging_win.h"
|
||||
#include "content/shell/common/v8_crashpad_support_win.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
|
||||
#include "v8/include/v8-wasm-trap-handler-posix.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#if !BUILDFLAG(IS_FUCHSIA)
|
||||
base::LazyInstance<content::ShellCrashReporterClient>::Leaky
|
||||
g_shell_crash_client = LAZY_INSTANCE_INITIALIZER;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// If "Content Shell" doesn't show up in your list of trace providers in
|
||||
// Sawbuck, add these registry entries to your machine (NOTE the optional
|
||||
// Wow6432Node key for x64 machines):
|
||||
// 1. Find: HKLM\SOFTWARE\[Wow6432Node\]Google\Sawbuck\Providers
|
||||
// 2. Add a subkey with the name "{6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}"
|
||||
// 3. Add these values:
|
||||
// "default_flags"=dword:00000001
|
||||
// "default_level"=dword:00000004
|
||||
// @="Content Shell"
|
||||
|
||||
// {6A3E50A4-7E15-4099-8413-EC94D8C2A4B6}
|
||||
const GUID kContentShellProviderName = {
|
||||
0x6a3e50a4, 0x7e15, 0x4099,
|
||||
{ 0x84, 0x13, 0xec, 0x94, 0xd8, 0xc2, 0xa4, 0xb6 } };
|
||||
#endif
|
||||
|
||||
void InitLogging(const base::CommandLine& command_line) {
|
||||
base::FilePath log_filename =
|
||||
command_line.GetSwitchValuePath(switches::kLogFile);
|
||||
if (log_filename.empty()) {
|
||||
#if BUILDFLAG(IS_FUCHSIA)
|
||||
base::PathService::Get(base::DIR_TEMP, &log_filename);
|
||||
#else
|
||||
base::PathService::Get(base::DIR_EXE, &log_filename);
|
||||
#endif
|
||||
log_filename = log_filename.AppendASCII("thorium_shell.log");
|
||||
}
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
settings.log_file_path = log_filename.value().c_str();
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
logging::InitLogging(settings);
|
||||
logging::SetLogItems(true /* Process ID */, true /* Thread ID */,
|
||||
true /* Timestamp */, false /* Tick count */);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace content {
|
||||
|
||||
ShellMainDelegate::ShellMainDelegate(bool is_content_browsertests)
|
||||
: is_content_browsertests_(is_content_browsertests) {}
|
||||
|
||||
ShellMainDelegate::~ShellMainDelegate() {
|
||||
}
|
||||
|
||||
bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
int dummy;
|
||||
if (!exit_code)
|
||||
exit_code = &dummy;
|
||||
|
||||
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch("run-layout-test")) {
|
||||
std::cerr << std::string(79, '*') << "\n"
|
||||
<< "* The flag --run-layout-test is obsolete. Please use --"
|
||||
<< switches::kRunWebTests << " instead. *\n"
|
||||
<< std::string(79, '*') << "\n";
|
||||
command_line.AppendSwitch(switches::kRunWebTests);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
Compositor::Initialize();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// Enable trace control and transport through event tracing for Windows.
|
||||
logging::LogEventProvider::Initialize(kContentShellProviderName);
|
||||
|
||||
v8_crashpad_support::SetUp();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// Needs to happen before InitializeResourceBundle().
|
||||
OverrideFrameworkBundlePath();
|
||||
OverrideOuterBundlePath();
|
||||
OverrideChildProcessPath();
|
||||
OverrideSourceRootPath();
|
||||
EnsureCorrectResolutionSettings();
|
||||
OverrideBundleID();
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
InitLogging(command_line);
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
if (switches::IsRunWebTestsSwitchPresent()) {
|
||||
const bool browser_process =
|
||||
command_line.GetSwitchValueASCII(switches::kProcessType).empty();
|
||||
if (browser_process) {
|
||||
web_test_runner_ = std::make_unique<WebTestBrowserMainRunner>();
|
||||
web_test_runner_->Initialize();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RegisterShellPathProvider();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ShellMainDelegate::ShouldCreateFeatureList(InvokedIn invoked_in) {
|
||||
return absl::holds_alternative<InvokedInChildProcess>(invoked_in);
|
||||
}
|
||||
|
||||
void ShellMainDelegate::PreSandboxStartup() {
|
||||
#if defined(ARCH_CPU_ARM_FAMILY) && \
|
||||
(BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
|
||||
// Create an instance of the CPU class to parse /proc/cpuinfo and cache
|
||||
// cpu_brand info.
|
||||
base::CPU cpu_info;
|
||||
#endif
|
||||
|
||||
// Disable platform crash handling and initialize the crash reporter, if
|
||||
// requested.
|
||||
// TODO(crbug.com/1226159): Implement crash reporter integration for Fuchsia.
|
||||
#if !BUILDFLAG(IS_FUCHSIA)
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableCrashReporter)) {
|
||||
std::string process_type =
|
||||
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
crash_reporter::SetCrashReporterClient(g_shell_crash_client.Pointer());
|
||||
// Reporting for sub-processes will be initialized in ZygoteForked.
|
||||
if (process_type != switches::kZygoteProcess) {
|
||||
crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
crash_reporter::SetFirstChanceExceptionHandler(
|
||||
v8::TryHandleWebAssemblyTrapPosix);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // !BUILDFLAG(IS_FUCHSIA)
|
||||
|
||||
crash_reporter::InitializeCrashKeys();
|
||||
|
||||
InitializeResourceBundle();
|
||||
}
|
||||
|
||||
absl::variant<int, MainFunctionParams> ShellMainDelegate::RunProcess(
|
||||
const std::string& process_type,
|
||||
MainFunctionParams main_function_params) {
|
||||
// For non-browser process, return and have the caller run the main loop.
|
||||
if (!process_type.empty())
|
||||
return std::move(main_function_params);
|
||||
|
||||
base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
|
||||
base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
|
||||
kTraceEventBrowserProcessSortIndex);
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
if (switches::IsRunWebTestsSwitchPresent()) {
|
||||
// Web tests implement their own BrowserMain() replacement.
|
||||
web_test_runner_->RunBrowserMain(std::move(main_function_params));
|
||||
web_test_runner_.reset();
|
||||
// Returning 0 to indicate that we have replaced BrowserMain() and the
|
||||
// caller should not call BrowserMain() itself. Web tests do not ever
|
||||
// return an error.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On non-Android, we can return the |main_function_params| back and have the
|
||||
// caller run BrowserMain() normally.
|
||||
return std::move(main_function_params);
|
||||
#else
|
||||
// On Android, we defer to the system message loop when the stack unwinds.
|
||||
// So here we only create (and leak) a BrowserMainRunner. The shutdown
|
||||
// of BrowserMainRunner doesn't happen in Chrome Android and doesn't work
|
||||
// properly on Android at all.
|
||||
std::unique_ptr<BrowserMainRunner> main_runner = BrowserMainRunner::Create();
|
||||
// In browser tests, the |main_function_params| contains a |ui_task| which
|
||||
// will execute the testing. The task will be executed synchronously inside
|
||||
// Initialize() so we don't depend on the BrowserMainRunner being Run().
|
||||
int initialize_exit_code =
|
||||
main_runner->Initialize(std::move(main_function_params));
|
||||
DCHECK_LT(initialize_exit_code, 0)
|
||||
<< "BrowserMainRunner::Initialize failed in ShellMainDelegate";
|
||||
std::ignore = main_runner.release();
|
||||
// Return 0 as BrowserMain() should not be called after this, bounce up to
|
||||
// the system message loop for ContentShell, and we're already done thanks
|
||||
// to the |ui_task| for browser tests.
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
void ShellMainDelegate::ZygoteForked() {
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableCrashReporter)) {
|
||||
std::string process_type =
|
||||
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
crash_reporter::InitializeCrashpad(false, process_type);
|
||||
crash_reporter::SetFirstChanceExceptionHandler(
|
||||
v8::TryHandleWebAssemblyTrapPosix);
|
||||
}
|
||||
}
|
||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
|
||||
void ShellMainDelegate::InitializeResourceBundle() {
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
// On Android, the renderer runs with a different UID and can never access
|
||||
// the file system. Use the file descriptor passed in at launch time.
|
||||
auto* global_descriptors = base::GlobalDescriptors::GetInstance();
|
||||
int pak_fd = global_descriptors->MaybeGet(kShellPakDescriptor);
|
||||
base::MemoryMappedFile::Region pak_region;
|
||||
if (pak_fd >= 0) {
|
||||
pak_region = global_descriptors->GetRegion(kShellPakDescriptor);
|
||||
} else {
|
||||
pak_fd =
|
||||
base::android::OpenApkAsset("assets/content_shell.pak", &pak_region);
|
||||
// Loaded from disk for browsertests.
|
||||
if (pak_fd < 0) {
|
||||
base::FilePath pak_file;
|
||||
bool r = base::PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_file);
|
||||
DCHECK(r);
|
||||
pak_file = pak_file.Append(FILE_PATH_LITERAL("paks"));
|
||||
pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
|
||||
int flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
||||
pak_fd = base::File(pak_file, flags).TakePlatformFile();
|
||||
pak_region = base::MemoryMappedFile::Region::kWholeFile;
|
||||
}
|
||||
global_descriptors->Set(kShellPakDescriptor, pak_fd, pak_region);
|
||||
}
|
||||
DCHECK_GE(pak_fd, 0);
|
||||
// TODO(crbug.com/330930): A better way to prevent fdsan error from a double
|
||||
// close is to refactor GlobalDescriptors.{Get,MaybeGet} to return
|
||||
// "const base::File&" rather than fd itself.
|
||||
base::File android_pak_file(pak_fd);
|
||||
ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
|
||||
android_pak_file.Duplicate(), pak_region);
|
||||
ui::ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion(
|
||||
std::move(android_pak_file), pak_region, ui::k100Percent);
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
ui::ResourceBundle::InitSharedInstanceWithPakPath(GetResourcesPakFilePath());
|
||||
#else
|
||||
base::FilePath pak_file;
|
||||
bool r = base::PathService::Get(base::DIR_ASSETS, &pak_file);
|
||||
DCHECK(r);
|
||||
pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
|
||||
ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShellMainDelegate::PreBrowserMain() {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
RegisterShellCrApp();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShellMainDelegate::PostEarlyInitialization(InvokedIn invoked_in) {
|
||||
if (!ShouldCreateFeatureList(invoked_in)) {
|
||||
// Apply field trial testing configuration since content did not.
|
||||
browser_client_->CreateFeatureListAndFieldTrials();
|
||||
}
|
||||
}
|
||||
|
||||
ContentClient* ShellMainDelegate::CreateContentClient() {
|
||||
content_client_ = std::make_unique<ShellContentClient>();
|
||||
return content_client_.get();
|
||||
}
|
||||
|
||||
ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() {
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
if (switches::IsRunWebTestsSwitchPresent()) {
|
||||
browser_client_ = std::make_unique<WebTestContentBrowserClient>();
|
||||
return browser_client_.get();
|
||||
}
|
||||
#endif
|
||||
browser_client_ = std::make_unique<ShellContentBrowserClient>();
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
ContentGpuClient* ShellMainDelegate::CreateContentGpuClient() {
|
||||
gpu_client_ = std::make_unique<ShellContentGpuClient>();
|
||||
return gpu_client_.get();
|
||||
}
|
||||
|
||||
ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
if (switches::IsRunWebTestsSwitchPresent()) {
|
||||
renderer_client_ = std::make_unique<WebTestContentRendererClient>();
|
||||
return renderer_client_.get();
|
||||
}
|
||||
#endif
|
||||
renderer_client_ = std::make_unique<ShellContentRendererClient>();
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
ContentUtilityClient* ShellMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_ =
|
||||
std::make_unique<ShellContentUtilityClient>(is_content_browsertests_);
|
||||
return utility_client_.get();
|
||||
}
|
||||
|
||||
} // namespace content
|
BIN
src/content/shell/app/thorium_shell.ico
Normal file
BIN
src/content/shell/app/thorium_shell.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
453
src/content/shell/browser/shell_platform_delegate_views.cc
Normal file
453
src/content/shell/browser/shell_platform_delegate_views.cc
Normal file
|
@ -0,0 +1,453 @@
|
|||
// 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 <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "content/public/browser/context_factory.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/shell/browser/shell.h"
|
||||
#include "content/shell/browser/shell_platform_delegate.h"
|
||||
#include "ui/aura/env.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/aura/window_event_dispatcher.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/base/clipboard/clipboard.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
#include "ui/base/metadata/metadata_impl_macros.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/color/color_id.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/controls/button/md_text_button.h"
|
||||
#include "ui/views/controls/textfield/textfield.h"
|
||||
#include "ui/views/controls/textfield/textfield_controller.h"
|
||||
#include "ui/views/controls/webview/webview.h"
|
||||
#include "ui/views/layout/box_layout_view.h"
|
||||
#include "ui/views/layout/flex_layout_types.h"
|
||||
#include "ui/views/layout/flex_layout_view.h"
|
||||
#include "ui/views/test/desktop_test_views_delegate.h"
|
||||
#include "ui/views/view.h"
|
||||
#include "ui/views/view_class_properties.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#include "ui/wm/test/wm_test_helper.h"
|
||||
#else // !BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_screen.h"
|
||||
#include "ui/wm/core/wm_state.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
|
||||
struct ShellPlatformDelegate::ShellData {
|
||||
gfx::Size content_size;
|
||||
// Self-owned Widget, destroyed through CloseNow().
|
||||
views::Widget* window_widget = nullptr;
|
||||
};
|
||||
|
||||
struct ShellPlatformDelegate::PlatformData {
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
std::unique_ptr<wm::WMTestHelper> wm_test_helper;
|
||||
#else
|
||||
std::unique_ptr<wm::WMState> wm_state;
|
||||
std::unique_ptr<display::Screen> screen;
|
||||
#endif
|
||||
|
||||
// TODO(danakj): This looks unused?
|
||||
std::unique_ptr<views::ViewsDelegate> views_delegate;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// Maintain the UI controls and web view for content shell
|
||||
class ShellView : public views::BoxLayoutView,
|
||||
public views::TextfieldController {
|
||||
public:
|
||||
METADATA_HEADER(ShellView);
|
||||
|
||||
enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON };
|
||||
|
||||
explicit ShellView(Shell* shell) : shell_(shell) { InitShellWindow(); }
|
||||
ShellView(const ShellView&) = delete;
|
||||
ShellView& operator=(const ShellView&) = delete;
|
||||
~ShellView() override = default;
|
||||
|
||||
// Update the state of UI controls
|
||||
void SetAddressBarURL(const GURL& url) {
|
||||
url_entry_->SetText(base::ASCIIToUTF16(url.spec()));
|
||||
}
|
||||
|
||||
void SetWebContents(WebContents* web_contents, const gfx::Size& size) {
|
||||
// If there was a previous WebView in this Shell it should be removed and
|
||||
// deleted.
|
||||
if (web_view_)
|
||||
contents_view_->RemoveChildViewT(web_view_.get());
|
||||
|
||||
views::Builder<views::View>(contents_view_)
|
||||
.AddChild(views::Builder<views::WebView>()
|
||||
.CopyAddressTo(&web_view_)
|
||||
.SetBrowserContext(web_contents->GetBrowserContext())
|
||||
.SetWebContents(web_contents)
|
||||
.SetPreferredSize(size))
|
||||
.BuildChildren();
|
||||
web_contents->Focus();
|
||||
web_view_->SizeToPreferredSize();
|
||||
|
||||
// Resize the widget, keeping the same origin.
|
||||
gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen();
|
||||
bounds.set_size(GetWidget()->GetRootView()->GetPreferredSize());
|
||||
GetWidget()->SetBounds(bounds);
|
||||
|
||||
// Resizing a widget on chromeos doesn't automatically resize the root, need
|
||||
// to explicitly do that.
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
GetWidget()->GetNativeWindow()->GetHost()->SetBoundsInPixels(bounds);
|
||||
#endif
|
||||
}
|
||||
|
||||
void EnableUIControl(UIControl control, bool is_enabled) {
|
||||
if (control == BACK_BUTTON) {
|
||||
back_button_->SetState(is_enabled ? views::Button::STATE_NORMAL
|
||||
: views::Button::STATE_DISABLED);
|
||||
} else if (control == FORWARD_BUTTON) {
|
||||
forward_button_->SetState(is_enabled ? views::Button::STATE_NORMAL
|
||||
: views::Button::STATE_DISABLED);
|
||||
} else if (control == STOP_BUTTON) {
|
||||
stop_button_->SetState(is_enabled ? views::Button::STATE_NORMAL
|
||||
: views::Button::STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Initialize the UI control contained in shell window
|
||||
void InitShellWindow() {
|
||||
auto toolbar_button_rule = [](const views::View* view,
|
||||
const views::SizeBounds& size_bounds) {
|
||||
gfx::Size preferred_size = view->GetPreferredSize();
|
||||
if (size_bounds != views::SizeBounds() &&
|
||||
size_bounds.width().is_bounded()) {
|
||||
preferred_size.set_width(std::max(
|
||||
std::min(size_bounds.width().value(), preferred_size.width()),
|
||||
preferred_size.width() / 2));
|
||||
}
|
||||
return preferred_size;
|
||||
};
|
||||
|
||||
auto builder =
|
||||
views::Builder<views::BoxLayoutView>(this)
|
||||
.SetBackground(
|
||||
views::CreateThemedSolidBackground(ui::kColorWindowBackground))
|
||||
.SetOrientation(views::BoxLayout::Orientation::kVertical);
|
||||
|
||||
if (!Shell::ShouldHideToolbar()) {
|
||||
builder.AddChild(
|
||||
views::Builder<views::FlexLayoutView>()
|
||||
.CopyAddressTo(&toolbar_view_)
|
||||
.SetOrientation(views::LayoutOrientation::kHorizontal)
|
||||
// Top padding = 2, Bottom padding = 5
|
||||
.SetProperty(views::kMarginsKey, gfx::Insets::TLBR(2, 0, 5, 0))
|
||||
.AddChildren(
|
||||
views::Builder<views::MdTextButton>()
|
||||
.CopyAddressTo(&back_button_)
|
||||
.SetText(u"Back")
|
||||
.SetCallback(base::BindRepeating(
|
||||
&Shell::GoBackOrForward,
|
||||
base::Unretained(shell_.get()), -1))
|
||||
.SetProperty(views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(base::BindRepeating(
|
||||
toolbar_button_rule))),
|
||||
views::Builder<views::MdTextButton>()
|
||||
.CopyAddressTo(&forward_button_)
|
||||
.SetText(u"Forward")
|
||||
.SetCallback(base::BindRepeating(
|
||||
&Shell::GoBackOrForward,
|
||||
base::Unretained(shell_.get()), 1))
|
||||
.SetProperty(views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(base::BindRepeating(
|
||||
toolbar_button_rule))),
|
||||
views::Builder<views::MdTextButton>()
|
||||
.CopyAddressTo(&refresh_button_)
|
||||
.SetText(u"Refresh")
|
||||
.SetCallback(base::BindRepeating(
|
||||
&Shell::Reload, base::Unretained(shell_.get())))
|
||||
.SetProperty(views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(base::BindRepeating(
|
||||
toolbar_button_rule))),
|
||||
views::Builder<views::MdTextButton>()
|
||||
.CopyAddressTo(&stop_button_)
|
||||
.SetText(u"Stop")
|
||||
.SetCallback(base::BindRepeating(
|
||||
&Shell::Stop, base::Unretained(shell_.get())))
|
||||
.SetProperty(views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(base::BindRepeating(
|
||||
toolbar_button_rule))),
|
||||
views::Builder<views::Textfield>()
|
||||
.CopyAddressTo(&url_entry_)
|
||||
.SetAccessibleName(u"Enter URL")
|
||||
.SetController(this)
|
||||
.SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_URL)
|
||||
.SetProperty(
|
||||
views::kFlexBehaviorKey,
|
||||
views::FlexSpecification(
|
||||
views::MinimumFlexSizeRule::kScaleToMinimum,
|
||||
views::MaximumFlexSizeRule::kUnbounded))
|
||||
// Left padding = 2, Right padding = 2
|
||||
.SetProperty(views::kMarginsKey,
|
||||
gfx::Insets::TLBR(0, 2, 0, 2))));
|
||||
}
|
||||
|
||||
builder.AddChild(views::Builder<views::View>()
|
||||
.CopyAddressTo(&contents_view_)
|
||||
.SetUseDefaultFillLayout(true)
|
||||
.CustomConfigure(base::BindOnce([](views::View* view) {
|
||||
if (!Shell::ShouldHideToolbar()) {
|
||||
view->SetProperty(views::kMarginsKey,
|
||||
gfx::Insets::TLBR(0, 2, 0, 2));
|
||||
}
|
||||
})));
|
||||
|
||||
if (!Shell::ShouldHideToolbar()) {
|
||||
builder.AddChild(views::Builder<views::View>().SetProperty(
|
||||
views::kMarginsKey, gfx::Insets::TLBR(0, 0, 5, 0)));
|
||||
}
|
||||
|
||||
std::move(builder).BuildChildren();
|
||||
SetFlexForView(contents_view_, 1);
|
||||
}
|
||||
void InitAccelerators() {
|
||||
// This function must be called when part of the widget hierarchy.
|
||||
DCHECK(GetWidget());
|
||||
static const ui::KeyboardCode keys[] = {ui::VKEY_F5, ui::VKEY_BROWSER_BACK,
|
||||
ui::VKEY_BROWSER_FORWARD};
|
||||
for (size_t i = 0; i < std::size(keys); ++i) {
|
||||
GetFocusManager()->RegisterAccelerator(
|
||||
ui::Accelerator(keys[i], ui::EF_NONE),
|
||||
ui::AcceleratorManager::kNormalPriority, this);
|
||||
}
|
||||
}
|
||||
// Overridden from TextfieldController
|
||||
void ContentsChanged(views::Textfield* sender,
|
||||
const std::u16string& new_contents) override {}
|
||||
bool HandleKeyEvent(views::Textfield* sender,
|
||||
const ui::KeyEvent& key_event) override {
|
||||
if (key_event.type() == ui::ET_KEY_PRESSED && sender == url_entry_ &&
|
||||
key_event.key_code() == ui::VKEY_RETURN) {
|
||||
std::string text = base::UTF16ToUTF8(url_entry_->GetText());
|
||||
GURL url(text);
|
||||
if (!url.has_scheme()) {
|
||||
url = GURL(std::string("http://") + std::string(text));
|
||||
url_entry_->SetText(base::ASCIIToUTF16(url.spec()));
|
||||
}
|
||||
shell_->LoadURL(url);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overridden from View
|
||||
gfx::Size GetMinimumSize() const override {
|
||||
// We want to be able to make the window smaller than its initial
|
||||
// (preferred) size.
|
||||
return gfx::Size();
|
||||
}
|
||||
void AddedToWidget() override { InitAccelerators(); }
|
||||
|
||||
// Overridden from AcceleratorTarget:
|
||||
bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
|
||||
switch (accelerator.key_code()) {
|
||||
case ui::VKEY_F5:
|
||||
shell_->Reload();
|
||||
return true;
|
||||
case ui::VKEY_BROWSER_BACK:
|
||||
shell_->GoBackOrForward(-1);
|
||||
return true;
|
||||
case ui::VKEY_BROWSER_FORWARD:
|
||||
shell_->GoBackOrForward(1);
|
||||
return true;
|
||||
default:
|
||||
return views::View::AcceleratorPressed(accelerator);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Shell> shell_;
|
||||
|
||||
// Window title
|
||||
std::u16string title_;
|
||||
|
||||
// Toolbar view contains forward/backward/reload button and URL entry
|
||||
raw_ptr<views::View> toolbar_view_ = nullptr;
|
||||
raw_ptr<views::Button> back_button_ = nullptr;
|
||||
raw_ptr<views::Button> forward_button_ = nullptr;
|
||||
raw_ptr<views::Button> refresh_button_ = nullptr;
|
||||
raw_ptr<views::Button> stop_button_ = nullptr;
|
||||
raw_ptr<views::Textfield> url_entry_ = nullptr;
|
||||
|
||||
// Contents view contains the web contents view
|
||||
raw_ptr<views::View> contents_view_ = nullptr;
|
||||
raw_ptr<views::WebView, DanglingUntriaged> web_view_ = nullptr;
|
||||
};
|
||||
|
||||
BEGIN_METADATA(ShellView, views::View)
|
||||
END_METADATA
|
||||
|
||||
ShellView* ShellViewForWidget(views::Widget* widget) {
|
||||
return static_cast<ShellView*>(widget->widget_delegate()->GetContentsView());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ShellPlatformDelegate::ShellPlatformDelegate() = default;
|
||||
|
||||
void ShellPlatformDelegate::Initialize(const gfx::Size& default_window_size) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
_setmode(_fileno(stderr), _O_BINARY);
|
||||
#endif
|
||||
|
||||
platform_ = std::make_unique<PlatformData>();
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
platform_->wm_test_helper =
|
||||
std::make_unique<wm::WMTestHelper>(default_window_size);
|
||||
#else
|
||||
platform_->wm_state = std::make_unique<wm::WMState>();
|
||||
// FakeScreen tests create their own screen.
|
||||
if (!display::Screen::HasScreen())
|
||||
platform_->screen = views::CreateDesktopScreen();
|
||||
#endif
|
||||
|
||||
platform_->views_delegate =
|
||||
std::make_unique<views::DesktopTestViewsDelegate>();
|
||||
}
|
||||
|
||||
ShellPlatformDelegate::~ShellPlatformDelegate() = default;
|
||||
|
||||
void ShellPlatformDelegate::CreatePlatformWindow(
|
||||
Shell* shell,
|
||||
const gfx::Size& initial_size) {
|
||||
DCHECK(!base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
shell_data.content_size = initial_size;
|
||||
|
||||
auto delegate = std::make_unique<views::WidgetDelegate>();
|
||||
delegate->SetContentsView(std::make_unique<ShellView>(shell));
|
||||
delegate->SetHasWindowSizeControls(true);
|
||||
delegate->SetOwnedByWidget(true);
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
shell_data.window_widget = views::Widget::CreateWindowWithContext(
|
||||
std::move(delegate),
|
||||
platform_->wm_test_helper->GetDefaultParent(nullptr, gfx::Rect()),
|
||||
gfx::Rect(initial_size));
|
||||
#else
|
||||
shell_data.window_widget = new views::Widget();
|
||||
views::Widget::InitParams params;
|
||||
params.bounds = gfx::Rect(initial_size);
|
||||
params.delegate = delegate.release();
|
||||
params.wm_class_class = "Thorium_Shell";
|
||||
params.wm_class_name = params.wm_class_class;
|
||||
shell_data.window_widget->Init(std::move(params));
|
||||
#endif
|
||||
|
||||
// |window_widget| is made visible in PlatformSetContents(), so that the
|
||||
// platform-window size does not need to change due to layout again.
|
||||
}
|
||||
|
||||
gfx::NativeWindow ShellPlatformDelegate::GetNativeWindow(Shell* shell) {
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
return shell_data.window_widget->GetNativeWindow();
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::CleanUp(Shell* shell) {
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
shell_data_map_.erase(shell);
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::SetContents(Shell* shell) {
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
ShellViewForWidget(shell_data.window_widget)
|
||||
->SetWebContents(shell->web_contents(), shell_data.content_size);
|
||||
shell_data.window_widget->GetNativeWindow()->GetHost()->Show();
|
||||
shell_data.window_widget->Show();
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::ResizeWebContent(Shell* shell,
|
||||
const gfx::Size& content_size) {
|
||||
shell->web_contents()->Resize(gfx::Rect(content_size));
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::EnableUIControl(Shell* shell,
|
||||
UIControl control,
|
||||
bool is_enabled) {
|
||||
if (Shell::ShouldHideToolbar())
|
||||
return;
|
||||
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
auto* view = ShellViewForWidget(shell_data.window_widget);
|
||||
if (control == BACK_BUTTON) {
|
||||
view->EnableUIControl(ShellView::BACK_BUTTON, is_enabled);
|
||||
} else if (control == FORWARD_BUTTON) {
|
||||
view->EnableUIControl(ShellView::FORWARD_BUTTON, is_enabled);
|
||||
} else if (control == STOP_BUTTON) {
|
||||
view->EnableUIControl(ShellView::STOP_BUTTON, is_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::SetAddressBarURL(Shell* shell, const GURL& url) {
|
||||
if (Shell::ShouldHideToolbar())
|
||||
return;
|
||||
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
ShellViewForWidget(shell_data.window_widget)->SetAddressBarURL(url);
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::SetIsLoading(Shell* shell, bool loading) {}
|
||||
|
||||
void ShellPlatformDelegate::SetTitle(Shell* shell,
|
||||
const std::u16string& title) {
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
shell_data.window_widget->widget_delegate()->SetTitle(title);
|
||||
}
|
||||
|
||||
void ShellPlatformDelegate::MainFrameCreated(Shell* shell) {}
|
||||
|
||||
bool ShellPlatformDelegate::DestroyShell(Shell* shell) {
|
||||
DCHECK(base::Contains(shell_data_map_, shell));
|
||||
ShellData& shell_data = shell_data_map_[shell];
|
||||
|
||||
shell_data.window_widget->CloseNow();
|
||||
return true; // The CloseNow() will do the destruction of Shell.
|
||||
}
|
||||
|
||||
} // namespace content
|
3106
src/content/test/BUILD.gn
Normal file
3106
src/content/test/BUILD.gn
Normal file
File diff suppressed because it is too large
Load diff
45
src/extensions/browser/ui_util.cc
Normal file
45
src/extensions/browser/ui_util.cc
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2022 The Chromium Authors and Alex313031. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "extensions/browser/ui_util.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "extensions/common/extension.h"
|
||||
#include "extensions/common/switches.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace ui_util {
|
||||
|
||||
bool ShouldDisplayInExtensionSettings(Manifest::Type type,
|
||||
mojom::ManifestLocation location) {
|
||||
// Don't show for themes since the settings UI isn't really useful for them.
|
||||
if (type == Manifest::TYPE_THEME)
|
||||
return true;
|
||||
|
||||
// Hide component extensions because they are only extensions as an
|
||||
// implementation detail of Chrome.
|
||||
if (Manifest::IsComponentLocation(location)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unless they are unpacked, never show hosted apps. Note: We intentionally
|
||||
// show packaged apps and platform apps because there are some pieces of
|
||||
// functionality that are only available in chrome://extensions/ but which
|
||||
// are needed for packaged and platform apps. For example, inspecting
|
||||
// background pages. See http://crbug.com/116134.
|
||||
if (!Manifest::IsUnpackedLocation(location) &&
|
||||
type == Manifest::TYPE_HOSTED_APP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShouldDisplayInExtensionSettings(const Extension& extension) {
|
||||
return ShouldDisplayInExtensionSettings(extension.GetType(),
|
||||
extension.location());
|
||||
}
|
||||
|
||||
} // namespace ui_util
|
||||
} // namespace extensions
|
Loading…
Reference in a new issue