0

[Mac] Stop performing direct NSColor lookups in the renderer process.

In blink::LayoutThemeMac, various system color properties are retrieved
from NSColor. These system colors are part of the "dynamic system color
store", and trying to access them may cause issues with the sandbox.

This augments the blink::WebSandboxSuport interface on Mac to look up
system colors via a shared memory segment that is populated by the
browser. In addition, this centralizes the various Mac implementations
of that interface into a single one.

      System Prefs>General and change the Highlight Color. Upon going
      back to Chrome, the new highlight color should be visible.

Bug: 641509, 36032
Test: Highlight some text on a web page. Then go to
Change-Id: I3bc05c08ecab62b1fc68442d3edd93ec7edb8590
Reviewed-on: https://chromium-review.googlesource.com/c/1331133
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Kent Tamura <tkent@chromium.org>
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609719}
This commit is contained in:
Robert Sesek
2018-11-20 16:00:10 +00:00
committed by Commit Bot
parent b4399282a5
commit 0694f7c1f9
24 changed files with 538 additions and 229 deletions

@ -1940,6 +1940,8 @@ jumbo_source_set("browser") {
sources += [ sources += [
"gpu/ca_transaction_gpu_coordinator.cc", "gpu/ca_transaction_gpu_coordinator.cc",
"gpu/ca_transaction_gpu_coordinator.h", "gpu/ca_transaction_gpu_coordinator.h",
"sandbox_support_mac_impl.h",
"sandbox_support_mac_impl.mm",
"web_contents/web_contents_ns_view_bridge.h", "web_contents/web_contents_ns_view_bridge.h",
"web_contents/web_contents_ns_view_bridge.mm", "web_contents/web_contents_ns_view_bridge.mm",
] ]

@ -0,0 +1,42 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_
#define CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_
#include "base/macros.h"
#include "content/common/sandbox_support_mac.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
namespace service_manager {
struct BindSourceInfo;
}
namespace content {
// Performs privileged operations on behalf of sandboxed child processes.
// This is used to implement the blink::WebSandboxSupport interface in the
// renderer. However all child process types have access to this interface.
// This class lives on the IO thread and is owned by the Mojo interface
// registry.
class SandboxSupportMacImpl : public mojom::SandboxSupportMac {
public:
SandboxSupportMacImpl();
~SandboxSupportMacImpl() override;
void BindRequest(mojom::SandboxSupportMacRequest request,
const service_manager::BindSourceInfo& source_info);
// content::mojom::SandboxSupportMac:
void GetSystemColors(GetSystemColorsCallback callback) override;
private:
mojo::BindingSet<mojom::SandboxSupportMac> bindings_;
DISALLOW_COPY_AND_ASSIGN(SandboxSupportMacImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_SANDBOX_SUPPORT_MAC_IMPL_H_

@ -0,0 +1,35 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "content/browser/sandbox_support_mac_impl.h"
#include "base/bind.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#import "content/browser/theme_helper_mac.h"
#include "content/public/browser/browser_task_traits.h"
namespace content {
SandboxSupportMacImpl::SandboxSupportMacImpl() = default;
SandboxSupportMacImpl::~SandboxSupportMacImpl() = default;
void SandboxSupportMacImpl::BindRequest(
mojom::SandboxSupportMacRequest request,
const service_manager::BindSourceInfo& source_info) {
bindings_.AddBinding(this, std::move(request));
}
void SandboxSupportMacImpl::GetSystemColors(GetSystemColorsCallback callback) {
auto task_runner =
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
base::PostTaskAndReplyWithResult(
task_runner.get(), FROM_HERE,
base::BindOnce(&ThemeHelperMac::DuplicateReadOnlyColorMapRegion,
base::Unretained(ThemeHelperMac::GetInstance())),
std::move(callback));
}
} // namespace content

@ -33,6 +33,7 @@
#include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h" #include "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"
#include "content/public/common/font_cache_dispatcher_win.h" #include "content/public/common/font_cache_dispatcher_win.h"
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
#include "content/browser/sandbox_support_mac_impl.h"
#include "content/common/font_loader_dispatcher_mac.h" #include "content/common/font_loader_dispatcher_mac.h"
#endif #endif
@ -51,6 +52,9 @@ class ConnectionFilterImpl : public ConnectionFilter {
{base::TaskPriority::USER_BLOCKING, base::MayBlock()})); {base::TaskPriority::USER_BLOCKING, base::MayBlock()}));
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
registry_.AddInterface(base::BindRepeating(&FontLoaderDispatcher::Create)); registry_.AddInterface(base::BindRepeating(&FontLoaderDispatcher::Create));
registry_.AddInterface(
base::BindRepeating(&SandboxSupportMacImpl::BindRequest,
base::Owned(new SandboxSupportMacImpl)));
#endif #endif
if (!features::IsMultiProcessMash()) { if (!features::IsMultiProcessMash()) {
// For mus, the mojom::discardable_memory::DiscardableSharedMemoryManager // For mus, the mojom::discardable_memory::DiscardableSharedMemoryManager

@ -6,13 +6,24 @@
#define CONTENT_BROWSER_THEME_HELPER_MAC_H_ #define CONTENT_BROWSER_THEME_HELPER_MAC_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/singleton.h" #include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/writable_shared_memory_region.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h"
#include "third_party/blink/public/platform/mac/web_scrollbar_theme.h" #include "third_party/blink/public/platform/mac/web_scrollbar_theme.h"
#if __OBJC__
@class SystemThemeObserver;
#else
class SystemThemeObserver;
#endif
namespace content { namespace content {
// This class is used to monitor macOS system appearance changes and to notify
// sandboxed child processes when they change. This class lives on the UI
// thread.
class ThemeHelperMac : public NotificationObserver { class ThemeHelperMac : public NotificationObserver {
public: public:
// Return pointer to the singleton instance for the current process, or NULL // Return pointer to the singleton instance for the current process, or NULL
@ -23,17 +34,33 @@ class ThemeHelperMac : public NotificationObserver {
// as the blink enum value. // as the blink enum value.
static blink::ScrollerStyle GetPreferredScrollerStyle(); static blink::ScrollerStyle GetPreferredScrollerStyle();
private: // Duplicates a handle to the read-only copy of the system color table,
friend struct base::DefaultSingletonTraits<ThemeHelperMac>; // which can be shared to sandboxed child processes.
base::ReadOnlySharedMemoryRegion DuplicateReadOnlyColorMapRegion();
private:
ThemeHelperMac(); ThemeHelperMac();
~ThemeHelperMac() override; ~ThemeHelperMac() override;
// Looks up the blink::MacSystemColorID corresponding to the NSColor
// selector and stores them in the |writable_color_map_| table.
void LoadSystemColors();
// Overridden from NotificationObserver: // Overridden from NotificationObserver:
void Observe(int type, void Observe(int type,
const NotificationSource& source, const NotificationSource& source,
const NotificationDetails& details) override; const NotificationDetails& details) override;
// ObjC object that observes notifications from the system.
SystemThemeObserver* theme_observer_; // strong
// Writable and mapped array of SkColor values, indexed by MacSystemColorID.
base::WritableSharedMemoryMapping writable_color_map_;
// Read-only handle to the |writable_color_map_| that can be duplicated for
// sharing to child processes.
base::ReadOnlySharedMemoryRegion read_only_color_map_;
NotificationRegistrar registrar_; NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(ThemeHelperMac); DISALLOW_COPY_AND_ASSIGN(ThemeHelperMac);

@ -4,10 +4,14 @@
#include "content/browser/theme_helper_mac.h" #include "content/browser/theme_helper_mac.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h"
@ -76,20 +80,109 @@ void SendSystemColorsChangedMessage(content::mojom::Renderer* renderer) {
[defaults stringForKey:@"AppleHighlightColor"])); [defaults stringForKey:@"AppleHighlightColor"]));
} }
SkColor NSColorToSkColor(NSColor* color) {
NSColor* color_in_color_space =
[color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
if (color_in_color_space) {
// Use nextafter() to avoid rounding colors in a way that could be off-by-
// one. See https://bugs.webkit.org/show_bug.cgi?id=6129.
static const double kScaleFactor = nextafter(256.0, 0.0);
return SkColorSetARGB(
static_cast<int>(kScaleFactor * [color_in_color_space alphaComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space redComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space greenComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space blueComponent]));
}
// This conversion above can fail if the NSColor in question is an
// NSPatternColor (as many system colors are). These colors are actually a
// repeating pattern not just a solid color. To work around this we simply
// draw a 1x1 image of the color and use that pixel's color. It might be
// better to use an average of the colors in the pattern instead.
base::scoped_nsobject<NSBitmapImageRep> offscreen_rep(
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:1
pixelsHigh:1
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:4
bitsPerPixel:32]);
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext
setCurrentContext:[NSGraphicsContext
graphicsContextWithBitmapImageRep:offscreen_rep]];
NSEraseRect(NSMakeRect(0, 0, 1, 1));
[color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
[NSGraphicsContext restoreGraphicsState];
NSUInteger pixel[4];
[offscreen_rep getPixel:pixel atX:0 y:0];
// This recursive call will not recurse again, because the color space
// the second time around is NSDeviceRGBColorSpace.
return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255.
green:pixel[1] / 255.
blue:pixel[2] / 255.
alpha:1.]);
}
SkColor MenuBackgroundColor() {
base::scoped_nsobject<NSBitmapImageRep> offscreen_rep(
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:1
pixelsHigh:1
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:4
bitsPerPixel:32]);
CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext
graphicsContextWithBitmapImageRep:offscreen_rep] graphicsPort]);
CGRect rect = CGRectMake(0, 0, 1, 1);
HIThemeMenuDrawInfo draw_info;
draw_info.version = 0;
draw_info.menuType = kThemeMenuTypePopUp;
HIThemeDrawMenuBackground(&rect, &draw_info, context,
kHIThemeOrientationInverted);
NSUInteger pixel[4];
[offscreen_rep getPixel:pixel atX:0 y:0];
return NSColorToSkColor([NSColor colorWithDeviceRed:pixel[0] / 255.
green:pixel[1] / 255.
blue:pixel[2] / 255.
alpha:1.]);
}
} // namespace } // namespace
@interface ScrollbarPrefsObserver : NSObject @interface SystemThemeObserver : NSObject {
base::RepeatingClosure colorsChangedCallback_;
}
+ (void)registerAsObserver; - (instancetype)initWithColorsChangedCallback:
+ (void)appearancePrefsChanged:(NSNotification*)notification; (base::RepeatingClosure)colorsChangedCallback;
+ (void)behaviorPrefsChanged:(NSNotification*)notification; - (void)appearancePrefsChanged:(NSNotification*)notification;
+ (void)notifyPrefsChangedWithRedraw:(BOOL)redraw; - (void)behaviorPrefsChanged:(NSNotification*)notification;
- (void)notifyPrefsChangedWithRedraw:(BOOL)redraw;
@end @end
@implementation ScrollbarPrefsObserver @implementation SystemThemeObserver
- (instancetype)initWithColorsChangedCallback:
(base::RepeatingClosure)colorsChangedCallback {
if (!(self = [super init])) {
return nil;
}
colorsChangedCallback_ = std::move(colorsChangedCallback);
+ (void)registerAsObserver {
NSDistributedNotificationCenter* distributedCenter = NSDistributedNotificationCenter* distributedCenter =
[NSDistributedNotificationCenter defaultCenter]; [NSDistributedNotificationCenter defaultCenter];
[distributedCenter addObserver:self [distributedCenter addObserver:self
@ -141,17 +234,26 @@ void SendSystemColorsChangedMessage(content::mojom::Renderer* renderer) {
name:NSSystemColorsDidChangeNotification name:NSSystemColorsDidChangeNotification
object:nil]; object:nil];
} }
return self;
} }
+ (void)appearancePrefsChanged:(NSNotification*)notification { - (void)dealloc {
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)appearancePrefsChanged:(NSNotification*)notification {
[self notifyPrefsChangedWithRedraw:YES]; [self notifyPrefsChangedWithRedraw:YES];
} }
+ (void)behaviorPrefsChanged:(NSNotification*)notification { - (void)behaviorPrefsChanged:(NSNotification*)notification {
[self notifyPrefsChangedWithRedraw:NO]; [self notifyPrefsChangedWithRedraw:NO];
} }
+ (void)systemColorsChanged:(NSNotification*)notification { - (void)systemColorsChanged:(NSNotification*)notification {
colorsChangedCallback_.Run();
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); !it.IsAtEnd();
it.Advance()) { it.Advance()) {
@ -160,7 +262,7 @@ void SendSystemColorsChangedMessage(content::mojom::Renderer* renderer) {
} }
} }
+ (void)notifyPrefsChangedWithRedraw:(BOOL)redraw { - (void)notifyPrefsChangedWithRedraw:(BOOL)redraw {
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); !it.IsAtEnd();
it.Advance()) { it.Advance()) {
@ -190,8 +292,8 @@ namespace content {
// static // static
ThemeHelperMac* ThemeHelperMac::GetInstance() { ThemeHelperMac* ThemeHelperMac::GetInstance() {
return base::Singleton<ThemeHelperMac, static ThemeHelperMac* instance = new ThemeHelperMac();
base::LeakySingletonTraits<ThemeHelperMac>>::get(); return instance;
} }
// static // static
@ -199,14 +301,112 @@ blink::ScrollerStyle ThemeHelperMac::GetPreferredScrollerStyle() {
return static_cast<blink::ScrollerStyle>([NSScroller preferredScrollerStyle]); return static_cast<blink::ScrollerStyle>([NSScroller preferredScrollerStyle]);
} }
base::ReadOnlySharedMemoryRegion
ThemeHelperMac::DuplicateReadOnlyColorMapRegion() {
return read_only_color_map_.Duplicate();
}
ThemeHelperMac::ThemeHelperMac() { ThemeHelperMac::ThemeHelperMac() {
[ScrollbarPrefsObserver registerAsObserver]; // Allocate a region for the SkColor value table and map it.
auto writable_region = base::WritableSharedMemoryRegion::Create(
sizeof(SkColor) * blink::kMacSystemColorIDCount);
writable_color_map_ = writable_region.Map();
// Downgrade the region to read-only after it has been mapped.
read_only_color_map_ = base::WritableSharedMemoryRegion::ConvertToReadOnly(
std::move(writable_region));
// Store the current color scheme into the table.
LoadSystemColors();
theme_observer_ = [[SystemThemeObserver alloc]
initWithColorsChangedCallback:base::BindRepeating(
&ThemeHelperMac::LoadSystemColors,
base::Unretained(this))];
registrar_.Add(this, registrar_.Add(this,
NOTIFICATION_RENDERER_PROCESS_CREATED, NOTIFICATION_RENDERER_PROCESS_CREATED,
NotificationService::AllSources()); NotificationService::AllSources());
} }
ThemeHelperMac::~ThemeHelperMac() { ThemeHelperMac::~ThemeHelperMac() {
[theme_observer_ release];
}
void ThemeHelperMac::LoadSystemColors() {
base::span<SkColor> values = writable_color_map_.GetMemoryAsSpan<SkColor>(
blink::kMacSystemColorIDCount);
for (size_t i = 0; i < blink::kMacSystemColorIDCount; ++i) {
blink::MacSystemColorID color_id = static_cast<blink::MacSystemColorID>(i);
switch (color_id) {
case blink::MacSystemColorID::kAlternateSelectedControl:
values[i] = NSColorToSkColor([NSColor alternateSelectedControlColor]);
break;
case blink::MacSystemColorID::kControlBackground:
values[i] = NSColorToSkColor([NSColor controlBackgroundColor]);
break;
case blink::MacSystemColorID::kControlDarkShadow:
values[i] = NSColorToSkColor([NSColor controlDarkShadowColor]);
break;
case blink::MacSystemColorID::kControlHighlight:
values[i] = NSColorToSkColor([NSColor controlHighlightColor]);
break;
case blink::MacSystemColorID::kControlLightHighlight:
values[i] = NSColorToSkColor([NSColor controlLightHighlightColor]);
break;
case blink::MacSystemColorID::kControlShadow:
values[i] = NSColorToSkColor([NSColor controlShadowColor]);
break;
case blink::MacSystemColorID::kControlText:
values[i] = NSColorToSkColor([NSColor controlTextColor]);
break;
case blink::MacSystemColorID::kDisabledControlText:
values[i] = NSColorToSkColor([NSColor disabledControlTextColor]);
break;
case blink::MacSystemColorID::kHeader:
values[i] = NSColorToSkColor([NSColor headerColor]);
break;
case blink::MacSystemColorID::kHighlight:
values[i] = NSColorToSkColor([NSColor highlightColor]);
break;
case blink::MacSystemColorID::kKeyboardFocusIndicator:
values[i] = NSColorToSkColor([NSColor keyboardFocusIndicatorColor]);
break;
case blink::MacSystemColorID::kMenuBackground:
values[i] = MenuBackgroundColor();
break;
case blink::MacSystemColorID::kScrollBar:
values[i] = NSColorToSkColor([NSColor scrollBarColor]);
break;
case blink::MacSystemColorID::kSecondarySelectedControl:
values[i] = NSColorToSkColor([NSColor secondarySelectedControlColor]);
break;
case blink::MacSystemColorID::kSelectedMenuItemText:
values[i] = NSColorToSkColor([NSColor selectedMenuItemTextColor]);
break;
case blink::MacSystemColorID::kSelectedText:
values[i] = NSColorToSkColor([NSColor selectedTextColor]);
break;
case blink::MacSystemColorID::kSelectedTextBackground:
values[i] = NSColorToSkColor([NSColor selectedTextBackgroundColor]);
break;
case blink::MacSystemColorID::kShadow:
values[i] = NSColorToSkColor([NSColor shadowColor]);
break;
case blink::MacSystemColorID::kText:
values[i] = NSColorToSkColor([NSColor textColor]);
break;
case blink::MacSystemColorID::kWindowBackground:
values[i] = NSColorToSkColor([NSColor windowBackgroundColor]);
break;
case blink::MacSystemColorID::kWindowFrame:
values[i] = NSColorToSkColor([NSColor windowFrameColor]);
break;
case blink::MacSystemColorID::kWindowFrameText:
values[i] = NSColorToSkColor([NSColor windowFrameTextColor]);
break;
case blink::MacSystemColorID::kCount:
NOTREACHED();
break;
}
}
} }
void ThemeHelperMac::Observe(int type, void ThemeHelperMac::Observe(int type,

@ -12,11 +12,27 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "content/common/mac/font_loader.h" #include "content/common/mac/font_loader.h"
#include "content/public/child/child_thread.h" #include "content/public/child/child_thread.h"
#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/buffer.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content { namespace content {
bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id) { WebSandboxSupportMac::WebSandboxSupportMac(
service_manager::Connector* connector) {
connector->BindInterface(content::mojom::kBrowserServiceName,
mojo::MakeRequest(&sandbox_support_));
sandbox_support_->GetSystemColors(base::BindOnce(
&WebSandboxSupportMac::OnGotSystemColors, base::Unretained(this)));
}
WebSandboxSupportMac::~WebSandboxSupportMac() = default;
// TODO(rsesek): Move font loading off the content.mojom.FontLoaderMac
// interface and onto the SandboxSupportMac interface.
bool WebSandboxSupportMac::LoadFont(CTFontRef font,
CGFontRef* out,
uint32_t* font_id) {
base::ScopedCFTypeRef<CFStringRef> name_ref(CTFontCopyPostScriptName(font)); base::ScopedCFTypeRef<CFStringRef> name_ref(CTFontCopyPostScriptName(font));
base::string16 font_name = SysCFStringRefToUTF16(name_ref); base::string16 font_name = SysCFStringRefToUTF16(name_ref);
float font_point_size = CTFontGetSize(font); float font_point_size = CTFontGetSize(font);
@ -42,4 +58,19 @@ bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id) {
std::move(font_data), static_cast<uint32_t>(font_data_size), out); std::move(font_data), static_cast<uint32_t>(font_data_size), out);
} }
SkColor WebSandboxSupportMac::GetSystemColor(blink::MacSystemColorID color_id) {
if (!color_map_.IsValid()) {
DLOG(ERROR) << "GetSystemColor does not have a valid color_map_";
return SK_ColorMAGENTA;
}
base::span<const SkColor> color_map =
color_map_.GetMemoryAsSpan<SkColor>(blink::kMacSystemColorIDCount);
return color_map[static_cast<size_t>(color_id)];
}
void WebSandboxSupportMac::OnGotSystemColors(
base::ReadOnlySharedMemoryRegion region) {
color_map_ = region.Map();
}
} // namespace content } // namespace content

@ -7,11 +7,37 @@
#include <CoreText/CoreText.h> #include <CoreText/CoreText.h>
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/shared_memory_mapping.h"
#include "content/common/sandbox_support_mac.mojom.h"
#include "third_party/blink/public/platform/mac/web_sandbox_support.h"
namespace service_manager {
class Connector;
}
namespace content { namespace content {
// Load a font specified by |font| into |out| through communicating // Implementation of the interface used by Blink to upcall to the privileged
// with browser. // process (browser) for handling requests for data that are not allowed within
bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id); // the sandbox.
class WebSandboxSupportMac : public blink::WebSandboxSupport {
public:
explicit WebSandboxSupportMac(service_manager::Connector* connector);
~WebSandboxSupportMac() override;
// blink::WebSandboxSupport:
bool LoadFont(CTFontRef font, CGFontRef* out, uint32_t* font_id) override;
SkColor GetSystemColor(blink::MacSystemColorID color_id) override;
private:
void OnGotSystemColors(base::ReadOnlySharedMemoryRegion region);
mojom::SandboxSupportMacPtr sandbox_support_;
base::ReadOnlySharedMemoryMapping color_map_;
DISALLOW_COPY_AND_ASSIGN(WebSandboxSupportMac);
};
}; // namespace content }; // namespace content

@ -548,6 +548,7 @@ mojom("mojo_bindings") {
sources += [ sources += [
"font_loader_mac.mojom", "font_loader_mac.mojom",
"render_widget_host_ns_view.mojom", "render_widget_host_ns_view.mojom",
"sandbox_support_mac.mojom",
] ]
} }

@ -0,0 +1,15 @@
// 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.
module content.mojom;
import "mojo/public/mojom/base/shared_memory.mojom";
// Interface for a sandboxed child process to request services of
// the browser.
interface SandboxSupportMac {
// Returns the shared memory region containing system theme color
// information.
GetSystemColors() => (mojo_base.mojom.ReadOnlySharedMemoryRegion region);
};

@ -19,7 +19,7 @@
#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_string.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "third_party/blink/public/platform/mac/web_sandbox_support.h" #include "content/child/child_process_sandbox_support_impl_mac.h"
#elif defined(OS_POSIX) && !defined(OS_ANDROID) #elif defined(OS_POSIX) && !defined(OS_ANDROID)
#include "content/child/child_process_sandbox_support_impl_linux.h" #include "content/child/child_process_sandbox_support_impl_linux.h"
#include "third_party/blink/public/platform/linux/out_of_process_font.h" #include "third_party/blink/public/platform/linux/out_of_process_font.h"
@ -36,19 +36,14 @@ typedef struct CGFont* CGFontRef;
namespace content { namespace content {
#if !defined(OS_ANDROID) && !defined(OS_WIN) #if defined(OS_LINUX)
class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport { class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
public: public:
#if defined(OS_LINUX)
explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
: font_loader_(std::move(font_loader)) {} : font_loader_(std::move(font_loader)) {}
#endif
~SandboxSupport() override {} ~SandboxSupport() override {}
#if defined(OS_MACOSX)
bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override;
#elif defined(OS_LINUX)
SandboxSupport(); SandboxSupport();
void GetFallbackFontForCharacter( void GetFallbackFontForCharacter(
WebUChar32 character, WebUChar32 character,
@ -72,23 +67,8 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
// For debugging https://crbug.com/312965 // For debugging https://crbug.com/312965
base::SequenceCheckerImpl creation_thread_sequence_checker_; base::SequenceCheckerImpl creation_thread_sequence_checker_;
#endif
}; };
#if defined(OS_MACOSX)
bool PpapiBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
CGFontRef* out,
uint32_t* font_id) {
// TODO(brettw) this should do the something similar to what
// RendererBlinkPlatformImpl does and request that the browser load the font.
// Note: need to unlock the proxy lock like ensureFontLoaded does.
NOTIMPLEMENTED();
return false;
}
#elif defined(OS_POSIX)
PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport() {} PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport() {}
void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter( void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
@ -137,8 +117,6 @@ void PpapiBlinkPlatformImpl::SandboxSupport::
#endif #endif
#endif // !defined(OS_ANDROID) && !defined(OS_WIN)
PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() { PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() {
#if defined(OS_LINUX) #if defined(OS_LINUX)
font_loader_ = font_loader_ =
@ -147,7 +125,8 @@ PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() {
sandbox_support_.reset( sandbox_support_.reset(
new PpapiBlinkPlatformImpl::SandboxSupport(font_loader_)); new PpapiBlinkPlatformImpl::SandboxSupport(font_loader_));
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport()); sandbox_support_.reset(
new WebSandboxSupportMac(ChildThread::Get()->GetConnector()));
#endif #endif
} }
@ -155,7 +134,7 @@ PpapiBlinkPlatformImpl::~PpapiBlinkPlatformImpl() {
} }
void PpapiBlinkPlatformImpl::Shutdown() { void PpapiBlinkPlatformImpl::Shutdown() {
#if !defined(OS_ANDROID) && !defined(OS_WIN) #if defined(OS_LINUX) || defined(OS_MACOSX)
// SandboxSupport contains a map of OutOfProcessFont objects, which hold // SandboxSupport contains a map of OutOfProcessFont objects, which hold
// WebStrings and WebVectors, which become invalidated when blink is shut // WebStrings and WebVectors, which become invalidated when blink is shut
// down. Hence, we need to clear that map now, just before blink::shutdown() // down. Hence, we need to clear that map now, just before blink::shutdown()
@ -165,7 +144,7 @@ void PpapiBlinkPlatformImpl::Shutdown() {
} }
blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() { blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() {
#if !defined(OS_ANDROID) && !defined(OS_WIN) #if defined(OS_LINUX) || defined(OS_MACOSX)
return sandbox_support_.get(); return sandbox_support_.get();
#else #else
return nullptr; return nullptr;

@ -42,12 +42,12 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
bool sync_dir) override; bool sync_dir) override;
private: private:
#if !defined(OS_ANDROID) && !defined(OS_WIN) #if defined(OS_LINUX) || defined(OS_MACOSX)
class SandboxSupport; std::unique_ptr<blink::WebSandboxSupport> sandbox_support_;
std::unique_ptr<SandboxSupport> sandbox_support_;
#endif #endif
#if defined(OS_LINUX) #if defined(OS_LINUX)
class SandboxSupport;
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
#endif #endif

@ -82,6 +82,9 @@
"viz.mojom.CompositingModeReporter", "viz.mojom.CompositingModeReporter",
"ws.mojom.Gpu" "ws.mojom.Gpu"
], ],
"sandbox_support": [
"content.mojom.SandboxSupportMac"
],
"service_manager:service_factory": [ "service_manager:service_factory": [
"service_manager.mojom.ServiceFactory" "service_manager.mojom.ServiceFactory"
] ]

@ -22,7 +22,8 @@
"dwrite_font_proxy", "dwrite_font_proxy",
"field_trials", "field_trials",
"font_cache", "font_cache",
"plugin" "plugin",
"sandbox_support"
], ],
"device": [ "device:power_monitor" ], "device": [ "device:power_monitor" ],
"font_service": [ "font_service" ], "font_service": [ "font_service" ],

@ -33,7 +33,8 @@
"dwrite_font_proxy", "dwrite_font_proxy",
"field_trials", "field_trials",
"font_loader", "font_loader",
"renderer" "renderer",
"sandbox_support"
], ],
"font_service": [ "font_service" ], "font_service": [ "font_service" ],
"metrics": [ "url_keyed_metrics" ], "metrics": [ "url_keyed_metrics" ],

@ -24,7 +24,8 @@
"content_browser": [ "content_browser": [
"dwrite_font_proxy", "dwrite_font_proxy",
"field_trials", "field_trials",
"font_cache" "font_cache",
"sandbox_support"
], ],
"device": [ "device": [
"device:power_monitor", "device:power_monitor",

@ -112,7 +112,6 @@
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "content/child/child_process_sandbox_support_impl_mac.h" #include "content/child/child_process_sandbox_support_impl_mac.h"
#include "content/common/mac/font_loader.h" #include "content/common/mac/font_loader.h"
#include "third_party/blink/public/platform/mac/web_sandbox_support.h"
#endif #endif
#if defined(OS_POSIX) #if defined(OS_POSIX)
@ -194,21 +193,14 @@ gpu::ContextType ToGpuContextType(blink::Platform::ContextType type) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) #if defined(OS_LINUX)
class RendererBlinkPlatformImpl::SandboxSupport class RendererBlinkPlatformImpl::SandboxSupport
: public blink::WebSandboxSupport { : public blink::WebSandboxSupport {
public: public:
#if defined(OS_LINUX)
explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
: font_loader_(std::move(font_loader)) {} : font_loader_(std::move(font_loader)) {}
#endif
~SandboxSupport() override {} ~SandboxSupport() override {}
#if defined(OS_MACOSX)
bool LoadFont(CTFontRef src_font,
CGFontRef* container,
uint32_t* font_id) override;
#elif defined(OS_LINUX)
void GetFallbackFontForCharacter( void GetFallbackFontForCharacter(
blink::WebUChar32 character, blink::WebUChar32 character,
const char* preferred_locale, const char* preferred_locale,
@ -230,9 +222,8 @@ class RendererBlinkPlatformImpl::SandboxSupport
base::Lock unicode_font_families_mutex_; base::Lock unicode_font_families_mutex_;
std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_; std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_;
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
#endif
}; };
#endif // !defined(OS_ANDROID) && !defined(OS_WIN) #endif // defined(OS_LINUX)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -265,10 +256,10 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
connector_ = service_manager::Connector::Create(&request); connector_ = service_manager::Connector::Create(&request);
} }
#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) #if defined(OS_LINUX) || defined(OS_MACOSX)
if (g_sandbox_enabled && sandboxEnabled()) { if (g_sandbox_enabled && sandboxEnabled()) {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport()); sandbox_support_.reset(new WebSandboxSupportMac(connector_.get()));
#else #else
sandbox_support_.reset( sandbox_support_.reset(
new RendererBlinkPlatformImpl::SandboxSupport(font_loader_)); new RendererBlinkPlatformImpl::SandboxSupport(font_loader_));
@ -294,7 +285,7 @@ RendererBlinkPlatformImpl::~RendererBlinkPlatformImpl() {
} }
void RendererBlinkPlatformImpl::Shutdown() { void RendererBlinkPlatformImpl::Shutdown() {
#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) #if defined(OS_LINUX) || defined(OS_MACOSX)
// SandboxSupport contains a map of OutOfProcessFont objects, which hold // SandboxSupport contains a map of OutOfProcessFont objects, which hold
// WebStrings and WebVectors, which become invalidated when blink is shut // WebStrings and WebVectors, which become invalidated when blink is shut
// down. Hence, we need to clear that map now, just before blink::shutdown() // down. Hence, we need to clear that map now, just before blink::shutdown()
@ -388,11 +379,11 @@ blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() {
} }
blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() { blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_FUCHSIA) #if defined(OS_LINUX) || defined(OS_MACOSX)
// These platforms do not require sandbox support.
return NULL;
#else
return sandbox_support_.get(); return sandbox_support_.get();
#else
// These platforms do not require sandbox support.
return nullptr;
#endif #endif
} }
@ -569,15 +560,7 @@ WebString RendererBlinkPlatformImpl::FileSystemCreateOriginIdentifier(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if defined(OS_MACOSX) #if defined(OS_LINUX)
bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
CGFontRef* out,
uint32_t* font_id) {
return content::LoadFont(src_font, out, font_id);
}
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter( void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
blink::WebUChar32 character, blink::WebUChar32 character,

@ -264,9 +264,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
std::unique_ptr<service_manager::Connector> connector_; std::unique_ptr<service_manager::Connector> connector_;
scoped_refptr<base::SingleThreadTaskRunner> io_runner_; scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) #if defined(OS_LINUX) || defined(OS_MACOSX)
class SandboxSupport; std::unique_ptr<blink::WebSandboxSupport> sandbox_support_;
std::unique_ptr<SandboxSupport> sandbox_support_;
#endif #endif
// This counter keeps track of the number of times sudden termination is // This counter keeps track of the number of times sudden termination is
@ -301,6 +300,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
scoped_refptr<blink::mojom::ThreadSafeCodeCacheHostPtr> code_cache_host_; scoped_refptr<blink::mojom::ThreadSafeCodeCacheHostPtr> code_cache_host_;
#if defined(OS_LINUX) #if defined(OS_LINUX)
class SandboxSupport;
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
#endif #endif

@ -9,8 +9,7 @@
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "content/child/child_process_sandbox_support_impl_mac.h" #include "content/child/child_process_sandbox_support_impl_mac.h"
#include "third_party/blink/public/platform/mac/web_sandbox_support.h" #elif defined(OS_LINUX)
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "content/child/child_process_sandbox_support_impl_linux.h" #include "content/child/child_process_sandbox_support_impl_linux.h"
#include "content/child/child_thread_impl.h" #include "content/child/child_thread_impl.h"
@ -27,20 +26,15 @@ struct WebFontRenderStyle;
namespace content { namespace content {
#if defined(OS_POSIX) && !defined(OS_ANDROID) #if defined(OS_LINUX)
class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
: public blink::WebSandboxSupport { : public blink::WebSandboxSupport {
public: public:
#if defined(OS_LINUX)
explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
: font_loader_(std::move(font_loader)) {} : font_loader_(std::move(font_loader)) {}
#endif
~SandboxSupport() override {} ~SandboxSupport() override {}
#if defined(OS_MACOSX)
bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override;
#else
void GetFallbackFontForCharacter( void GetFallbackFontForCharacter(
blink::WebUChar32 character, blink::WebUChar32 character,
const char* preferred_locale, const char* preferred_locale,
@ -63,10 +57,9 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
// Maps unicode chars to their fallback fonts. // Maps unicode chars to their fallback fonts.
std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_; std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_;
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
#endif // defined(OS_MACOSX)
}; };
#endif // defined(OS_POSIX) && !defined(OS_ANDROID) #endif // defined(OS_LINUX)
UtilityBlinkPlatformWithSandboxSupportImpl:: UtilityBlinkPlatformWithSandboxSupportImpl::
UtilityBlinkPlatformWithSandboxSupportImpl( UtilityBlinkPlatformWithSandboxSupportImpl(
@ -76,7 +69,7 @@ UtilityBlinkPlatformWithSandboxSupportImpl::
SkFontConfigInterface::SetGlobal(font_loader_); SkFontConfigInterface::SetGlobal(font_loader_);
sandbox_support_ = std::make_unique<SandboxSupport>(font_loader_); sandbox_support_ = std::make_unique<SandboxSupport>(font_loader_);
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
sandbox_support_ = std::make_unique<SandboxSupport>(); sandbox_support_ = std::make_unique<WebSandboxSupportMac>(connector);
#endif #endif
} }
@ -85,23 +78,14 @@ UtilityBlinkPlatformWithSandboxSupportImpl::
blink::WebSandboxSupport* blink::WebSandboxSupport*
UtilityBlinkPlatformWithSandboxSupportImpl::GetSandboxSupport() { UtilityBlinkPlatformWithSandboxSupportImpl::GetSandboxSupport() {
#if defined(OS_POSIX) && !defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_MACOSX)
return sandbox_support_.get(); return sandbox_support_.get();
#else #else
return nullptr; return nullptr;
#endif #endif
} }
#if defined(OS_MACOSX) #if defined(OS_LINUX)
bool UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::LoadFont(
CTFontRef src_font,
CGFontRef* out,
uint32_t* font_id) {
return content::LoadFont(src_font, out, font_id);
}
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport:: void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
GetFallbackFontForCharacter(blink::WebUChar32 character, GetFallbackFontForCharacter(blink::WebUChar32 character,

@ -11,7 +11,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#if defined(OS_POSIX) && !defined(OS_ANDROID) #if defined(OS_LINUX)
#include "components/services/font/public/cpp/font_loader.h" // nogncheck #include "components/services/font/public/cpp/font_loader.h" // nogncheck
#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck #include "third_party/skia/include/core/SkRefCnt.h" // nogncheck
#endif #endif
@ -39,11 +39,11 @@ class UtilityBlinkPlatformWithSandboxSupportImpl : public blink::Platform {
blink::WebSandboxSupport* GetSandboxSupport() override; blink::WebSandboxSupport* GetSandboxSupport() override;
private: private:
#if defined(OS_POSIX) && !defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_MACOSX)
class SandboxSupport; std::unique_ptr<blink::WebSandboxSupport> sandbox_support_;
std::unique_ptr<SandboxSupport> sandbox_support_;
#endif #endif
#if defined(OS_LINUX) #if defined(OS_LINUX)
class SandboxSupport;
sk_sp<font_service::FontLoader> font_loader_; sk_sp<font_service::FontLoader> font_loader_;
#endif #endif

@ -112,6 +112,10 @@ source_set("headers") {
deps += [ ":font_unique_name_table_proto" ] deps += [ ":font_unique_name_table_proto" ]
} }
if (is_mac) {
sources += [ "sandbox_support/sandbox_support_mac.h" ]
}
if (is_win) { if (is_win) {
sources += [ "dwrite_rasterizer_support/dwrite_rasterizer_support.h" ] sources += [ "dwrite_rasterizer_support/dwrite_rasterizer_support.h" ]
} }

@ -0,0 +1,43 @@
// 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.
#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_
namespace blink {
// Named Mac system colors. Each of these corresponds to a selector on
// NSColor.
enum class MacSystemColorID {
kAlternateSelectedControl,
kControlBackground,
kControlDarkShadow,
kControlHighlight,
kControlLightHighlight,
kControlShadow,
kControlText,
kDisabledControlText,
kHeader,
kHighlight,
kKeyboardFocusIndicator,
kMenuBackground,
kScrollBar,
kSecondarySelectedControl,
kSelectedMenuItemText,
kSelectedText,
kSelectedTextBackground,
kShadow,
kText,
kWindowBackground,
kWindowFrame,
kWindowFrameText,
kCount,
};
constexpr size_t kMacSystemColorIDCount =
static_cast<size_t>(MacSystemColorID::kCount);
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_SANDBOX_SUPPORT_SANDBOX_SUPPORT_MAC_H_

@ -31,6 +31,9 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MAC_WEB_SANDBOX_SUPPORT_H_
#include "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h"
#include "third_party/skia/include/core/SkColor.h"
typedef struct CGFont* CGFontRef; typedef struct CGFont* CGFontRef;
namespace blink { namespace blink {
@ -52,6 +55,9 @@ class WebSandboxSupport {
virtual bool LoadFont(CTFontRef src_font, virtual bool LoadFont(CTFontRef src_font,
CGFontRef* out, CGFontRef* out,
uint32_t* font_id) = 0; uint32_t* font_id) = 0;
// Returns the system's preferred value for a named color.
virtual SkColor GetSystemColor(MacSystemColorID) = 0;
}; };
} // namespace blink } // namespace blink

@ -24,6 +24,9 @@
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <math.h> #import <math.h>
#import "third_party/blink/public/platform/mac/web_sandbox_support.h"
#import "third_party/blink/public/platform/platform.h"
#import "third_party/blink/renderer/core/css_value_keywords.h" #import "third_party/blink/renderer/core/css_value_keywords.h"
#import "third_party/blink/renderer/core/fileapi/file_list.h" #import "third_party/blink/renderer/core/fileapi/file_list.h"
#import "third_party/blink/renderer/core/html_names.h" #import "third_party/blink/renderer/core/html_names.h"
@ -128,8 +131,13 @@ bool FontSizeMatchesToControlSize(const ComputedStyle& style) {
return false; return false;
} }
NSColor* ColorInColorSpace(NSColor* color) { Color GetSystemColor(MacSystemColorID color_id) {
return [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; // In tests, a WebSandboxSupport may not be set up. Just return a dummy
// color, in this case, black.
auto* sandbox_support = Platform::Current()->GetSandboxSupport();
if (!sandbox_support)
return Color();
return sandbox_support->GetSystemColor(color_id);
} }
} // namespace } // namespace
@ -153,17 +161,11 @@ LayoutThemeMac::~LayoutThemeMac() {
} }
Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor() const { Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor() const {
NSColor* color = ColorInColorSpace([NSColor selectedTextBackgroundColor]); return GetSystemColor(MacSystemColorID::kSelectedTextBackground);
return Color(static_cast<int>(255.0 * [color redComponent]),
static_cast<int>(255.0 * [color greenComponent]),
static_cast<int>(255.0 * [color blueComponent]));
} }
Color LayoutThemeMac::PlatformInactiveSelectionBackgroundColor() const { Color LayoutThemeMac::PlatformInactiveSelectionBackgroundColor() const {
NSColor* color = ColorInColorSpace([NSColor secondarySelectedControlColor]); return GetSystemColor(MacSystemColorID::kSecondarySelectedControl);
return Color(static_cast<int>(255.0 * [color redComponent]),
static_cast<int>(255.0 * [color greenComponent]),
static_cast<int>(255.0 * [color blueComponent]));
} }
Color LayoutThemeMac::PlatformActiveSelectionForegroundColor() const { Color LayoutThemeMac::PlatformActiveSelectionForegroundColor() const {
@ -171,10 +173,7 @@ Color LayoutThemeMac::PlatformActiveSelectionForegroundColor() const {
} }
Color LayoutThemeMac::PlatformActiveListBoxSelectionBackgroundColor() const { Color LayoutThemeMac::PlatformActiveListBoxSelectionBackgroundColor() const {
NSColor* color = ColorInColorSpace([NSColor alternateSelectedControlColor]); return GetSystemColor(MacSystemColorID::kAlternateSelectedControl);
return Color(static_cast<int>(255.0 * [color redComponent]),
static_cast<int>(255.0 * [color greenComponent]),
static_cast<int>(255.0 * [color blueComponent]));
} }
Color LayoutThemeMac::PlatformActiveListBoxSelectionForegroundColor() const { Color LayoutThemeMac::PlatformActiveListBoxSelectionForegroundColor() const {
@ -263,84 +262,6 @@ void LayoutThemeMac::SystemFont(CSSValueID system_font_id,
font_family = font_family_names::kSystemUi; font_family = font_family_names::kSystemUi;
} }
static RGBA32 ConvertNSColorToColor(NSColor* color) {
NSColor* color_in_color_space = ColorInColorSpace(color);
if (color_in_color_space) {
static const double kScaleFactor = nextafter(256.0, 0.0);
return MakeRGBA(
static_cast<int>(kScaleFactor * [color_in_color_space redComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space greenComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space blueComponent]),
static_cast<int>(kScaleFactor * [color_in_color_space alphaComponent]));
}
// This conversion above can fail if the NSColor in question is an
// NSPatternColor (as many system colors are). These colors are actually a
// repeating pattern not just a solid color. To work around this we simply
// draw a 1x1 image of the color and use that pixel's color. It might be
// better to use an average of the colors in the pattern instead.
NSBitmapImageRep* offscreen_rep =
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:1
pixelsHigh:1
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:4
bitsPerPixel:32];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext
setCurrentContext:[NSGraphicsContext
graphicsContextWithBitmapImageRep:offscreen_rep]];
NSEraseRect(NSMakeRect(0, 0, 1, 1));
[color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
[NSGraphicsContext restoreGraphicsState];
NSUInteger pixel[4];
[offscreen_rep getPixel:pixel atX:0 y:0];
[offscreen_rep release];
// This recursive call will not recurse again, because the color space
// the second time around is NSDeviceRGBColorSpace.
return ConvertNSColorToColor([NSColor colorWithDeviceRed:pixel[0] / 255.
green:pixel[1] / 255.
blue:pixel[2] / 255.
alpha:1.]);
}
static RGBA32 MenuBackgroundColor() {
NSBitmapImageRep* offscreen_rep =
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
pixelsWide:1
pixelsHigh:1
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:4
bitsPerPixel:32];
CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext
graphicsContextWithBitmapImageRep:offscreen_rep] graphicsPort]);
CGRect rect = CGRectMake(0, 0, 1, 1);
HIThemeMenuDrawInfo draw_info;
draw_info.version = 0;
draw_info.menuType = kThemeMenuTypePopUp;
HIThemeDrawMenuBackground(&rect, &draw_info, context,
kHIThemeOrientationInverted);
NSUInteger pixel[4];
[offscreen_rep getPixel:pixel atX:0 y:0];
[offscreen_rep release];
return ConvertNSColorToColor([NSColor colorWithDeviceRed:pixel[0] / 255.
green:pixel[1] / 255.
blue:pixel[2] / 255.
alpha:1.]);
}
void LayoutThemeMac::PlatformColorsDidChange() { void LayoutThemeMac::PlatformColorsDidChange() {
system_color_cache_.clear(); system_color_cache_.clear();
LayoutTheme::PlatformColorsDidChange(); LayoutTheme::PlatformColorsDidChange();
@ -357,50 +278,50 @@ Color LayoutThemeMac::SystemColor(CSSValueID css_value_id) const {
bool needs_fallback = false; bool needs_fallback = false;
switch (css_value_id) { switch (css_value_id) {
case CSSValueActiveborder: case CSSValueActiveborder:
color = ConvertNSColorToColor([NSColor keyboardFocusIndicatorColor]); color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator);
break; break;
case CSSValueActivecaption: case CSSValueActivecaption:
color = ConvertNSColorToColor([NSColor windowFrameTextColor]); color = GetSystemColor(MacSystemColorID::kWindowFrameText);
break; break;
case CSSValueAppworkspace: case CSSValueAppworkspace:
color = ConvertNSColorToColor([NSColor headerColor]); color = GetSystemColor(MacSystemColorID::kHeader);
break; break;
case CSSValueBackground: case CSSValueBackground:
// Use theme independent default // Use theme independent default
needs_fallback = true; needs_fallback = true;
break; break;
case CSSValueButtonface: case CSSValueButtonface:
color = ConvertNSColorToColor([NSColor controlBackgroundColor]); color = GetSystemColor(MacSystemColorID::kControlBackground);
break; break;
case CSSValueButtonhighlight: case CSSValueButtonhighlight:
color = ConvertNSColorToColor([NSColor controlHighlightColor]); color = GetSystemColor(MacSystemColorID::kControlHighlight);
break; break;
case CSSValueButtonshadow: case CSSValueButtonshadow:
color = ConvertNSColorToColor([NSColor controlShadowColor]); color = GetSystemColor(MacSystemColorID::kControlShadow);
break; break;
case CSSValueButtontext: case CSSValueButtontext:
color = ConvertNSColorToColor([NSColor controlTextColor]); color = GetSystemColor(MacSystemColorID::kControlText);
break; break;
case CSSValueCaptiontext: case CSSValueCaptiontext:
color = ConvertNSColorToColor([NSColor textColor]); color = GetSystemColor(MacSystemColorID::kText);
break; break;
case CSSValueGraytext: case CSSValueGraytext:
color = ConvertNSColorToColor([NSColor disabledControlTextColor]); color = GetSystemColor(MacSystemColorID::kDisabledControlText);
break; break;
case CSSValueHighlight: case CSSValueHighlight:
color = ConvertNSColorToColor([NSColor selectedTextBackgroundColor]); color = GetSystemColor(MacSystemColorID::kSelectedTextBackground);
break; break;
case CSSValueHighlighttext: case CSSValueHighlighttext:
color = ConvertNSColorToColor([NSColor selectedTextColor]); color = GetSystemColor(MacSystemColorID::kSelectedText);
break; break;
case CSSValueInactiveborder: case CSSValueInactiveborder:
color = ConvertNSColorToColor([NSColor controlBackgroundColor]); color = GetSystemColor(MacSystemColorID::kControlBackground);
break; break;
case CSSValueInactivecaption: case CSSValueInactivecaption:
color = ConvertNSColorToColor([NSColor controlBackgroundColor]); color = GetSystemColor(MacSystemColorID::kControlBackground);
break; break;
case CSSValueInactivecaptiontext: case CSSValueInactivecaptiontext:
color = ConvertNSColorToColor([NSColor textColor]); color = GetSystemColor(MacSystemColorID::kText);
break; break;
case CSSValueInfobackground: case CSSValueInfobackground:
// There is no corresponding NSColor for this so we use a hard coded // There is no corresponding NSColor for this so we use a hard coded
@ -408,25 +329,25 @@ Color LayoutThemeMac::SystemColor(CSSValueID css_value_id) const {
color = 0xFFFBFCC5; color = 0xFFFBFCC5;
break; break;
case CSSValueInfotext: case CSSValueInfotext:
color = ConvertNSColorToColor([NSColor textColor]); color = GetSystemColor(MacSystemColorID::kText);
break; break;
case CSSValueMenu: case CSSValueMenu:
color = MenuBackgroundColor(); color = GetSystemColor(MacSystemColorID::kMenuBackground);
break; break;
case CSSValueMenutext: case CSSValueMenutext:
color = ConvertNSColorToColor([NSColor selectedMenuItemTextColor]); color = GetSystemColor(MacSystemColorID::kSelectedMenuItemText);
break; break;
case CSSValueScrollbar: case CSSValueScrollbar:
color = ConvertNSColorToColor([NSColor scrollBarColor]); color = GetSystemColor(MacSystemColorID::kScrollBar);
break; break;
case CSSValueText: case CSSValueText:
color = ConvertNSColorToColor([NSColor textColor]); color = GetSystemColor(MacSystemColorID::kText);
break; break;
case CSSValueThreeddarkshadow: case CSSValueThreeddarkshadow:
color = ConvertNSColorToColor([NSColor controlDarkShadowColor]); color = GetSystemColor(MacSystemColorID::kControlDarkShadow);
break; break;
case CSSValueThreedshadow: case CSSValueThreedshadow:
color = ConvertNSColorToColor([NSColor shadowColor]); color = GetSystemColor(MacSystemColorID::kShadow);
break; break;
case CSSValueThreedface: case CSSValueThreedface:
// We use this value instead of NSColor's controlColor to avoid website // We use this value instead of NSColor's controlColor to avoid website
@ -435,22 +356,22 @@ Color LayoutThemeMac::SystemColor(CSSValueID css_value_id) const {
color = 0xFFC0C0C0; color = 0xFFC0C0C0;
break; break;
case CSSValueThreedhighlight: case CSSValueThreedhighlight:
color = ConvertNSColorToColor([NSColor highlightColor]); color = GetSystemColor(MacSystemColorID::kHighlight);
break; break;
case CSSValueThreedlightshadow: case CSSValueThreedlightshadow:
color = ConvertNSColorToColor([NSColor controlLightHighlightColor]); color = GetSystemColor(MacSystemColorID::kControlLightHighlight);
break; break;
case CSSValueWebkitFocusRingColor: case CSSValueWebkitFocusRingColor:
color = ConvertNSColorToColor([NSColor keyboardFocusIndicatorColor]); color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator);
break; break;
case CSSValueWindow: case CSSValueWindow:
color = ConvertNSColorToColor([NSColor windowBackgroundColor]); color = GetSystemColor(MacSystemColorID::kWindowBackground);
break; break;
case CSSValueWindowframe: case CSSValueWindowframe:
color = ConvertNSColorToColor([NSColor windowFrameColor]); color = GetSystemColor(MacSystemColorID::kWindowFrame);
break; break;
case CSSValueWindowtext: case CSSValueWindowtext:
color = ConvertNSColorToColor([NSColor windowFrameTextColor]); color = GetSystemColor(MacSystemColorID::kWindowFrameText);
break; break;
default: default:
needs_fallback = true; needs_fallback = true;