summaryrefslogtreecommitdiff
path: root/chromium/content/shell/app
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/shell/app')
-rw-r--r--chromium/content/shell/app/DEPS11
-rw-r--r--chromium/content/shell/app/app-Info.plist32
-rw-r--r--chromium/content/shell/app/app.icnsbin0 -> 55080 bytes
-rw-r--r--chromium/content/shell/app/framework-Info.plist18
-rw-r--r--chromium/content/shell/app/helper-Info.plist28
-rw-r--r--chromium/content/shell/app/paths_mac.h30
-rw-r--r--chromium/content/shell/app/paths_mac.mm96
-rw-r--r--chromium/content/shell/app/resource.h41
-rw-r--r--chromium/content/shell/app/shell.rc146
-rw-r--r--chromium/content/shell/app/shell_content_main.cc29
-rw-r--r--chromium/content/shell/app/shell_content_main.h18
-rw-r--r--chromium/content/shell/app/shell_crash_reporter_client.cc95
-rw-r--r--chromium/content/shell/app/shell_crash_reporter_client.h61
-rw-r--r--chromium/content/shell/app/shell_main.cc46
-rw-r--r--chromium/content/shell/app/shell_main_delegate.cc381
-rw-r--r--chromium/content/shell/app/shell_main_delegate.h77
-rw-r--r--chromium/content/shell/app/shell_main_delegate_mac.h22
-rw-r--r--chromium/content/shell/app/shell_main_delegate_mac.mm72
-rw-r--r--chromium/content/shell/app/shell_main_mac.cc102
19 files changed, 1305 insertions, 0 deletions
diff --git a/chromium/content/shell/app/DEPS b/chromium/content/shell/app/DEPS
new file mode 100644
index 00000000000..f64b894c822
--- /dev/null
+++ b/chromium/content/shell/app/DEPS
@@ -0,0 +1,11 @@
+include_rules = [
+]
+
+specific_include_rules = {
+ "shell_main_delegate\.cc": [
+ # Separating Content Shell and web test code. ShellMainDelegate injects web test
+ # code into Content Shell at runtime.
+ "+content/web_test/browser",
+ "+content/web_test/renderer",
+ ],
+}
diff --git a/chromium/content/shell/app/app-Info.plist b/chromium/content/shell/app/app-Info.plist
new file mode 100644
index 00000000000..65b019e3e2b
--- /dev/null
+++ b/chromium/content/shell/app/app-Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>app.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.chromium.ContentShell</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>LSFileQuarantineEnabled</key>
+ <true/>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+ <key>NSBluetoothAlwaysUsageDescription</key>
+ <string>Content Shell may use Bluetooth to implement Web Platform features.</string>
+</dict>
+</plist>
diff --git a/chromium/content/shell/app/app.icns b/chromium/content/shell/app/app.icns
new file mode 100644
index 00000000000..f36742de257
--- /dev/null
+++ b/chromium/content/shell/app/app.icns
Binary files differ
diff --git a/chromium/content/shell/app/framework-Info.plist b/chromium/content/shell/app/framework-Info.plist
new file mode 100644
index 00000000000..ee19476052d
--- /dev/null
+++ b/chromium/content/shell/app/framework-Info.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.chromium.ContentShell.framework</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+</dict>
+</plist>
diff --git a/chromium/content/shell/app/helper-Info.plist b/chromium/content/shell/app/helper-Info.plist
new file mode 100644
index 00000000000..2503b29efca
--- /dev/null
+++ b/chromium/content/shell/app/helper-Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.chromium.ContentShell.helper${CONTENT_SHELL_HELPER_BUNDLE_ID_SUFFIX}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>LSFileQuarantineEnabled</key>
+ <true/>
+ <key>LSUIElement</key>
+ <string>1</string>
+ <key>NSSupportsAutomaticGraphicsSwitching</key>
+ <true/>
+</dict>
+</plist>
diff --git a/chromium/content/shell/app/paths_mac.h b/chromium/content/shell/app/paths_mac.h
new file mode 100644
index 00000000000..e704128cfee
--- /dev/null
+++ b/chromium/content/shell/app/paths_mac.h
@@ -0,0 +1,30 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_APP_PATHS_MAC_H_
+#define CONTENT_SHELL_APP_PATHS_MAC_H_
+
+namespace base {
+class FilePath;
+}
+
+// Sets up base::mac::FrameworkBundle.
+void OverrideFrameworkBundlePath();
+
+// Set up base::mac::OuterBundle.
+void OverrideOuterBundlePath();
+
+// Sets up the CHILD_PROCESS_EXE path to properly point to the helper app.
+void OverrideChildProcessPath();
+
+// Sets up base::DIR_SOURCE_ROOT to properly point to the source directory.
+void OverrideSourceRootPath();
+
+// Gets the path to the content shell's pak file.
+base::FilePath GetResourcesPakFilePath();
+
+// Gets the path to content shell's Info.plist file.
+base::FilePath GetInfoPlistPath();
+
+#endif // CONTENT_SHELL_APP_PATHS_MAC_H_
diff --git a/chromium/content/shell/app/paths_mac.mm b/chromium/content/shell/app/paths_mac.mm
new file mode 100644
index 00000000000..c43cb6cadda
--- /dev/null
+++ b/chromium/content/shell/app/paths_mac.mm
@@ -0,0 +1,96 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/app/paths_mac.h"
+
+#include "base/base_paths.h"
+#include "base/mac/bundle_locations.h"
+#include "base/mac/foundation_util.h"
+#include "base/path_service.h"
+#include "content/public/common/content_paths.h"
+
+namespace {
+
+base::FilePath GetContentsPath() {
+ // Start out with the path to the running executable.
+ base::FilePath path;
+ base::PathService::Get(base::FILE_EXE, &path);
+
+ // Up to Contents.
+ if (base::mac::IsBackgroundOnlyProcess()) {
+ // The running executable is the helper, located at:
+ // Content Shell.app/Contents/Frameworks/
+ // Content Shell Framework.framework/Versions/C/Helpers/Content Shell
+ // Helper.app/ Contents/MacOS/Content Shell Helper. Go up nine steps to get
+ // to the main bundle's Contents directory.
+ path = path.DirName()
+ .DirName()
+ .DirName()
+ .DirName()
+ .DirName()
+ .DirName()
+ .DirName()
+ .DirName()
+ .DirName();
+ } else {
+ // One step up to MacOS, another to Contents.
+ path = path.DirName().DirName();
+ }
+ DCHECK_EQ("Contents", path.BaseName().value());
+
+ return path;
+}
+
+base::FilePath GetFrameworksPath() {
+ return GetContentsPath().Append("Frameworks");
+}
+
+} // namespace
+
+void OverrideFrameworkBundlePath() {
+ base::FilePath helper_path =
+ GetFrameworksPath().Append("Content Shell Framework.framework");
+
+ base::mac::SetOverrideFrameworkBundlePath(helper_path);
+}
+
+void OverrideOuterBundlePath() {
+ base::FilePath path = GetContentsPath().DirName();
+
+ base::mac::SetOverrideOuterBundlePath(path);
+}
+
+void OverrideChildProcessPath() {
+ base::FilePath helper_path = base::mac::FrameworkBundlePath()
+ .Append("Helpers")
+ .Append("Content Shell Helper.app")
+ .Append("Contents")
+ .Append("MacOS")
+ .Append("Content Shell Helper");
+
+ base::PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
+}
+
+void OverrideSourceRootPath() {
+ // The base implementation to get base::DIR_SOURCE_ROOT assumes the current
+ // process path is the top level app path, not a nested one.
+ //
+ // Going up 5 levels is needed, since frameworks path looks something like
+ // src/out/foo/Content Shell.app/Contents/Framework/
+ base::PathService::Override(
+ base::DIR_SOURCE_ROOT,
+ GetFrameworksPath().DirName().DirName().DirName().DirName().DirName());
+}
+
+base::FilePath GetResourcesPakFilePath() {
+ NSString* pak_path =
+ [base::mac::FrameworkBundle() pathForResource:@"content_shell"
+ ofType:@"pak"];
+
+ return base::FilePath([pak_path fileSystemRepresentation]);
+}
+
+base::FilePath GetInfoPlistPath() {
+ return GetContentsPath().Append("Info.plist");
+}
diff --git a/chromium/content/shell/app/resource.h b/chromium/content/shell/app/resource.h
new file mode 100644
index 00000000000..29bb74dfa78
--- /dev/null
+++ b/chromium/content/shell/app/resource.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by test_shell.rc
+//
+
+
+#define IDR_MAINFRAME 128
+#define IDM_EXIT 105
+#define IDM_CLOSE_WINDOW 106
+#define IDM_NEW_WINDOW 107
+#define IDM_SHOW_DEVELOPER_TOOLS 108
+#define IDC_CONTENTSHELL 109
+#define IDD_ALERT 130
+#define IDD_CONFIRM 131
+#define IDD_PROMPT 132
+#define IDC_NAV_BACK 1001
+#define IDC_NAV_FORWARD 1002
+#define IDC_NAV_RELOAD 1003
+#define IDC_NAV_STOP 1004
+#define IDC_PROMPTEDIT 1005
+#define IDC_DIALOGTEXT 1006
+
+#ifndef IDC_STATIC
+#define IDC_STATIC -1
+#endif
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NO_MFC 130
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 117
+#endif
+#endif
diff --git a/chromium/content/shell/app/shell.rc b/chromium/content/shell/app/shell.rc
new file mode 100644
index 00000000000..2987c067570
--- /dev/null
+++ b/chromium/content/shell/app/shell.rc
@@ -0,0 +1,146 @@
+//Microsoft Visual C++ generated resource script.
+//
+#include "content/shell/app/resource.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
diff --git a/chromium/content/shell/app/shell_content_main.cc b/chromium/content/shell/app/shell_content_main.cc
new file mode 100644
index 00000000000..fc0caafbea8
--- /dev/null
+++ b/chromium/content/shell/app/shell_content_main.cc
@@ -0,0 +1,29 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/app/shell_content_main.h"
+
+#include "build/build_config.h"
+#include "content/public/app/content_main.h"
+#include "content/public/common/content_switches.h"
+#include "content/shell/app/shell_main_delegate.h"
+
+#if BUILDFLAG(IS_MAC)
+int ContentMain(int argc,
+ const char** argv) {
+ bool is_browsertest = false;
+ std::string browser_test_flag(std::string("--") + switches::kBrowserTest);
+ for (int i = 0; i < argc; ++i) {
+ if (browser_test_flag == argv[i]) {
+ is_browsertest = true;
+ break;
+ }
+ }
+ content::ShellMainDelegate delegate(is_browsertest);
+ content::ContentMainParams params(&delegate);
+ params.argc = argc;
+ params.argv = argv;
+ return content::ContentMain(std::move(params));
+}
+#endif // BUILDFLAG(IS_MAC)
diff --git a/chromium/content/shell/app/shell_content_main.h b/chromium/content/shell/app/shell_content_main.h
new file mode 100644
index 00000000000..58bcbab9a1a
--- /dev/null
+++ b/chromium/content/shell/app/shell_content_main.h
@@ -0,0 +1,18 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_APP_SHELL_CONTENT_MAIN_H_
+#define CONTENT_SHELL_APP_SHELL_CONTENT_MAIN_H_
+
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_MAC)
+extern "C" {
+__attribute__((visibility("default")))
+int ContentMain(int argc,
+ const char** argv);
+} // extern "C"
+#endif // BUILDFLAG(IS_MAC)
+
+#endif // CONTENT_SHELL_APP_SHELL_CONTENT_MAIN_H_
diff --git a/chromium/content/shell/app/shell_crash_reporter_client.cc b/chromium/content/shell/app/shell_crash_reporter_client.cc
new file mode 100644
index 00000000000..4c76c176753
--- /dev/null
+++ b/chromium/content/shell/app/shell_crash_reporter_client.cc
@@ -0,0 +1,95 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/app/shell_crash_reporter_client.h"
+
+#include <string>
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "content/public/common/content_switches.h"
+#include "content/shell/common/shell_switches.h"
+
+#if BUILDFLAG(IS_ANDROID)
+#include "content/shell/android/shell_descriptors.h"
+#endif
+
+namespace content {
+
+ShellCrashReporterClient::ShellCrashReporterClient() {}
+ShellCrashReporterClient::~ShellCrashReporterClient() {}
+
+#if BUILDFLAG(IS_WIN)
+void ShellCrashReporterClient::GetProductNameAndVersion(
+ const std::wstring& exe_path,
+ std::wstring* product_name,
+ std::wstring* version,
+ std::wstring* special_build,
+ std::wstring* channel_name) {
+ *product_name = L"content_shell";
+ *version = base::ASCIIToWide(CONTENT_SHELL_VERSION);
+ *special_build = std::wstring();
+ *channel_name = std::wstring();
+}
+#endif
+
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
+void ShellCrashReporterClient::GetProductNameAndVersion(
+ const char** product_name,
+ const char** version) {
+ *product_name = "content_shell";
+ *version = CONTENT_SHELL_VERSION;
+}
+
+void ShellCrashReporterClient::GetProductNameAndVersion(
+ std::string* product_name,
+ std::string* version,
+ std::string* channel) {
+ *product_name = "content_shell";
+ *version = CONTENT_SHELL_VERSION;
+ *channel = "";
+}
+
+base::FilePath ShellCrashReporterClient::GetReporterLogFilename() {
+ return base::FilePath(FILE_PATH_LITERAL("uploads.log"));
+}
+#endif
+
+#if BUILDFLAG(IS_WIN)
+bool ShellCrashReporterClient::GetCrashDumpLocation(std::wstring* crash_dir) {
+#else
+bool ShellCrashReporterClient::GetCrashDumpLocation(base::FilePath* crash_dir) {
+#endif
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kCrashDumpsDir))
+ return false;
+ base::FilePath crash_directory =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+ switches::kCrashDumpsDir);
+#if BUILDFLAG(IS_WIN)
+ *crash_dir = crash_directory.value();
+#else
+ *crash_dir = std::move(crash_directory);
+#endif
+ return true;
+}
+
+#if BUILDFLAG(IS_ANDROID)
+int ShellCrashReporterClient::GetAndroidMinidumpDescriptor() {
+ return kAndroidMinidumpDescriptor;
+}
+#endif
+
+bool ShellCrashReporterClient::EnableBreakpadForProcess(
+ const std::string& process_type) {
+ return process_type == switches::kRendererProcess ||
+ process_type == switches::kPpapiPluginProcess ||
+ process_type == switches::kZygoteProcess ||
+ process_type == switches::kGpuProcess;
+}
+
+} // namespace content
diff --git a/chromium/content/shell/app/shell_crash_reporter_client.h b/chromium/content/shell/app/shell_crash_reporter_client.h
new file mode 100644
index 00000000000..3eb37a61932
--- /dev/null
+++ b/chromium/content/shell/app/shell_crash_reporter_client.h
@@ -0,0 +1,61 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_APP_SHELL_CRASH_REPORTER_CLIENT_H_
+#define CONTENT_SHELL_APP_SHELL_CRASH_REPORTER_CLIENT_H_
+
+#include "build/build_config.h"
+#include "components/crash/core/app/crash_reporter_client.h"
+
+namespace content {
+
+class ShellCrashReporterClient : public crash_reporter::CrashReporterClient {
+ public:
+ ShellCrashReporterClient();
+
+ ShellCrashReporterClient(const ShellCrashReporterClient&) = delete;
+ ShellCrashReporterClient& operator=(const ShellCrashReporterClient&) = delete;
+
+ ~ShellCrashReporterClient() override;
+
+#if BUILDFLAG(IS_WIN)
+ // Returns a textual description of the product type and version to include
+ // in the crash report.
+ void GetProductNameAndVersion(const std::wstring& exe_path,
+ std::wstring* product_name,
+ std::wstring* version,
+ std::wstring* special_build,
+ std::wstring* channel_name) override;
+#endif
+
+#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
+ // Returns a textual description of the product type and version to include
+ // in the crash report.
+ void GetProductNameAndVersion(const char** product_name,
+ const char** version) override;
+ void GetProductNameAndVersion(std::string* product_name,
+ std::string* version,
+ std::string* channel) override;
+ base::FilePath GetReporterLogFilename() override;
+#endif
+
+ // The location where minidump files should be written. Returns true if
+ // |crash_dir| was set.
+#if BUILDFLAG(IS_WIN)
+ bool GetCrashDumpLocation(std::wstring* crash_dir) override;
+#else
+ bool GetCrashDumpLocation(base::FilePath* crash_dir) override;
+#endif
+
+#if BUILDFLAG(IS_ANDROID)
+ // Returns the descriptor key of the android minidump global descriptor.
+ int GetAndroidMinidumpDescriptor() override;
+#endif
+
+ bool EnableBreakpadForProcess(const std::string& process_type) override;
+};
+
+} // namespace content
+
+#endif // CONTENT_SHELL_APP_SHELL_CRASH_REPORTER_CLIENT_H_
diff --git a/chromium/content/shell/app/shell_main.cc b/chromium/content/shell/app/shell_main.cc
new file mode 100644
index 00000000000..421a4857d2d
--- /dev/null
+++ b/chromium/content/shell/app/shell_main.cc
@@ -0,0 +1,46 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+#include "content/public/app/content_main.h"
+#include "content/shell/app/shell_main_delegate.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "base/win/win_util.h"
+#include "content/public/app/sandbox_helper_win.h"
+#include "sandbox/win/src/sandbox_types.h"
+#endif
+
+#if BUILDFLAG(IS_WIN)
+
+#if !defined(WIN_CONSOLE_APP)
+int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) {
+#else
+int main() {
+ HINSTANCE instance = GetModuleHandle(NULL);
+#endif
+ // Load and pin user32.dll to avoid having to load it once tests start while
+ // on the main thread loop where blocking calls are disallowed.
+ base::win::PinUser32();
+ sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
+ content::InitializeSandboxInfo(&sandbox_info);
+ content::ShellMainDelegate delegate;
+
+ content::ContentMainParams params(&delegate);
+ params.instance = instance;
+ params.sandbox_info = &sandbox_info;
+ return content::ContentMain(std::move(params));
+}
+
+#else
+
+int main(int argc, const char** argv) {
+ content::ShellMainDelegate delegate;
+ content::ContentMainParams params(&delegate);
+ params.argc = argc;
+ params.argv = argv;
+ return content::ContentMain(std::move(params));
+}
+
+#endif // BUILDFLAG(IS_WIN)
diff --git a/chromium/content/shell/app/shell_main_delegate.cc b/chromium/content/shell/app/shell_main_delegate.cc
new file mode 100644
index 00000000000..86e85bdc4ea
--- /dev/null
+++ b/chromium/content/shell/app/shell_main_delegate.cc
@@ -0,0 +1,381 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "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 "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("content_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() {
+ return false;
+}
+
+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(bool is_running_tests) {
+ // Apply field trial testing configuration.
+ 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
diff --git a/chromium/content/shell/app/shell_main_delegate.h b/chromium/content/shell/app/shell_main_delegate.h
new file mode 100644
index 00000000000..f19ee28d6c8
--- /dev/null
+++ b/chromium/content/shell/app/shell_main_delegate.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_H_
+#define CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_H_
+
+#include <memory>
+
+#include "build/build_config.h"
+#include "content/public/app/content_main_delegate.h"
+
+namespace content {
+class ShellContentClient;
+class ShellContentBrowserClient;
+class ShellContentGpuClient;
+class ShellContentRendererClient;
+class ShellContentUtilityClient;
+
+#if !BUILDFLAG(IS_ANDROID)
+class WebTestBrowserMainRunner;
+#endif
+
+class ShellMainDelegate : public ContentMainDelegate {
+ public:
+ explicit ShellMainDelegate(bool is_content_browsertests = false);
+
+ ShellMainDelegate(const ShellMainDelegate&) = delete;
+ ShellMainDelegate& operator=(const ShellMainDelegate&) = delete;
+
+ ~ShellMainDelegate() override;
+
+ // ContentMainDelegate implementation:
+ bool BasicStartupComplete(int* exit_code) override;
+ bool ShouldCreateFeatureList() override;
+ void PreSandboxStartup() override;
+ absl::variant<int, MainFunctionParams> RunProcess(
+ const std::string& process_type,
+ MainFunctionParams main_function_params) override;
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+ void ZygoteForked() override;
+#endif
+ void PreBrowserMain() override;
+ void PostEarlyInitialization(bool is_running_tests) override;
+ ContentClient* CreateContentClient() override;
+ ContentBrowserClient* CreateContentBrowserClient() override;
+ ContentGpuClient* CreateContentGpuClient() override;
+ ContentRendererClient* CreateContentRendererClient() override;
+ ContentUtilityClient* CreateContentUtilityClient() override;
+
+ static void InitializeResourceBundle();
+
+ protected:
+ // Only present when running content_browsertests, which run inside Content
+ // Shell.
+ //
+ // content_browsertests should not set the kRunWebTests command line flag, so
+ // |is_content_browsertests_| and |web_test_runner_| are mututally exclusive.
+ bool is_content_browsertests_;
+#if !BUILDFLAG(IS_ANDROID)
+ // Only present when running web tests, which run inside Content Shell.
+ //
+ // Web tests are not browser tests, so |is_content_browsertests_| and
+ // |web_test_runner_| are mututally exclusive.
+ std::unique_ptr<WebTestBrowserMainRunner> web_test_runner_;
+#endif
+
+ std::unique_ptr<ShellContentBrowserClient> browser_client_;
+ std::unique_ptr<ShellContentGpuClient> gpu_client_;
+ std::unique_ptr<ShellContentRendererClient> renderer_client_;
+ std::unique_ptr<ShellContentUtilityClient> utility_client_;
+ std::unique_ptr<ShellContentClient> content_client_;
+};
+
+} // namespace content
+
+#endif // CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_H_
diff --git a/chromium/content/shell/app/shell_main_delegate_mac.h b/chromium/content/shell/app/shell_main_delegate_mac.h
new file mode 100644
index 00000000000..fe9696855c1
--- /dev/null
+++ b/chromium/content/shell/app/shell_main_delegate_mac.h
@@ -0,0 +1,22 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_MAC_H_
+#define CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_MAC_H_
+
+namespace content {
+
+// Set NSHighResolutionCapable to false when running layout tests, so we match
+// the expected pixel results on retina capable displays.
+void EnsureCorrectResolutionSettings();
+
+// Sets up base::mac::BaseBundleID.
+void OverrideBundleID();
+
+// Initializes NSApplication.
+void RegisterShellCrApp();
+
+} // namespace content
+
+#endif // CONTENT_SHELL_APP_SHELL_MAIN_DELEGATE_MAC_H_
diff --git a/chromium/content/shell/app/shell_main_delegate_mac.mm b/chromium/content/shell/app/shell_main_delegate_mac.mm
new file mode 100644
index 00000000000..c1c3917db0b
--- /dev/null
+++ b/chromium/content/shell/app/shell_main_delegate_mac.mm
@@ -0,0 +1,72 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/shell/app/shell_main_delegate_mac.h"
+
+#include <unistd.h>
+
+#include "base/check.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/mac/bundle_locations.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
+#include "content/public/common/content_switches.h"
+#include "content/shell/app/paths_mac.h"
+#include "content/shell/browser/shell_application_mac.h"
+#include "content/shell/common/shell_switches.h"
+
+namespace content {
+
+void EnsureCorrectResolutionSettings() {
+ // Exit early if this isn't a browser process.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType))
+ return;
+
+ NSString* const kHighResolutionCapable = @"NSHighResolutionCapable";
+ base::FilePath info_plist = GetInfoPlistPath();
+ base::scoped_nsobject<NSMutableDictionary> info_dict(
+ [[NSMutableDictionary alloc]
+ initWithContentsOfFile:base::mac::FilePathToNSString(info_plist)]);
+
+ bool running_web_tests = switches::IsRunWebTestsSwitchPresent();
+ bool not_high_resolution_capable =
+ [info_dict objectForKey:kHighResolutionCapable] &&
+ [[info_dict objectForKey:kHighResolutionCapable] isEqualToNumber:@(NO)];
+ if (running_web_tests == not_high_resolution_capable)
+ return;
+
+ // We need to update our Info.plist before we can continue.
+ [info_dict setObject:@(!running_web_tests) forKey:kHighResolutionCapable];
+ CHECK([info_dict writeToFile:base::mac::FilePathToNSString(info_plist)
+ atomically:YES]);
+
+ const base::CommandLine::StringVector& original_argv =
+ base::CommandLine::ForCurrentProcess()->argv();
+ char** argv = new char*[original_argv.size() + 1];
+ for (unsigned i = 0; i < original_argv.size(); ++i)
+ argv[i] = const_cast<char*>(original_argv.at(i).c_str());
+ argv[original_argv.size()] = NULL;
+
+ CHECK(execvp(argv[0], argv));
+}
+
+void OverrideBundleID() {
+ NSBundle* bundle = base::mac::OuterBundle();
+ base::mac::SetBaseBundleID(
+ base::SysNSStringToUTF8([bundle bundleIdentifier]).c_str());
+}
+
+void RegisterShellCrApp() {
+ // Force the NSApplication subclass to be used.
+ [ShellCrApplication sharedApplication];
+
+ // If there was an invocation to NSApp prior to this method, then the NSApp
+ // will not be a ShellCrApplication, but will instead be an NSApplication.
+ // This is undesirable and we must enforce that this doesn't happen.
+ CHECK([NSApp isKindOfClass:[ShellCrApplication class]]);
+}
+
+} // namespace content
diff --git a/chromium/content/shell/app/shell_main_mac.cc b/chromium/content/shell/app/shell_main_mac.cc
new file mode 100644
index 00000000000..0097ce687a5
--- /dev/null
+++ b/chromium/content/shell/app/shell_main_mac.cc
@@ -0,0 +1,102 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <libgen.h>
+#include <mach-o/dyld.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <memory>
+
+#include "base/allocator/early_zone_registration_mac.h"
+
+#if defined(HELPER_EXECUTABLE)
+#include "sandbox/mac/seatbelt_exec.h" // nogncheck
+#endif // defined(HELPER_EXECUTABLE)
+
+namespace {
+
+using ContentMainPtr = int (*)(int, char**);
+
+} // namespace
+
+int main(int argc, char* argv[]) {
+ partition_alloc::EarlyMallocZoneRegistration();
+
+ uint32_t exec_path_size = 0;
+ int rv = _NSGetExecutablePath(NULL, &exec_path_size);
+ if (rv != -1) {
+ fprintf(stderr, "_NSGetExecutablePath: get length failed\n");
+ abort();
+ }
+
+ std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
+ rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
+ if (rv != 0) {
+ fprintf(stderr, "_NSGetExecutablePath: get path failed\n");
+ abort();
+ }
+
+#if defined(HELPER_EXECUTABLE)
+ sandbox::SeatbeltExecServer::CreateFromArgumentsResult seatbelt =
+ sandbox::SeatbeltExecServer::CreateFromArguments(exec_path.get(), argc,
+ argv);
+ if (seatbelt.sandbox_required) {
+ if (!seatbelt.server) {
+ fprintf(stderr, "Failed to create seatbelt sandbox server.\n");
+ abort();
+ }
+ if (!seatbelt.server->InitializeSandbox()) {
+ fprintf(stderr, "Failed to initialize sandbox.\n");
+ abort();
+ }
+ }
+
+ // The Helper app is in the versioned framework directory, so just go up to
+ // the version folder to locate the dylib.
+ const char rel_path[] = "../../../../" SHELL_PRODUCT_NAME " Framework";
+#else
+ const char rel_path[] =
+ "../Frameworks/" SHELL_PRODUCT_NAME
+ " Framework.framework/" SHELL_PRODUCT_NAME " Framework";
+#endif // defined(HELPER_EXECUTABLE)
+
+ // Slice off the last part of the main executable path, and append the
+ // version framework information.
+ const char* parent_dir = dirname(exec_path.get());
+ if (!parent_dir) {
+ fprintf(stderr, "dirname %s: %s\n", exec_path.get(), strerror(errno));
+ abort();
+ }
+
+ const size_t parent_dir_len = strlen(parent_dir);
+ const size_t rel_path_len = strlen(rel_path);
+ // 2 accounts for a trailing NUL byte and the '/' in the middle of the paths.
+ const size_t framework_path_size = parent_dir_len + rel_path_len + 2;
+ std::unique_ptr<char[]> framework_path(new char[framework_path_size]);
+ snprintf(framework_path.get(), framework_path_size, "%s/%s", parent_dir,
+ rel_path);
+
+ void* library =
+ dlopen(framework_path.get(), RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
+ if (!library) {
+ fprintf(stderr, "dlopen %s: %s\n", framework_path.get(), dlerror());
+ abort();
+ }
+
+ const ContentMainPtr content_main =
+ reinterpret_cast<ContentMainPtr>(dlsym(library, "ContentMain"));
+ if (!content_main) {
+ fprintf(stderr, "dlsym ContentMain: %s\n", dlerror());
+ abort();
+ }
+ rv = content_main(argc, argv);
+
+ // exit, don't return from main, to avoid the apparent removal of main from
+ // stack backtraces under tail call optimization.
+ exit(rv);
+}