blob: b61a8cc0bbdfedea9d1d82f6d226092a2bb86457 [file] [log] [blame]
[email protected]ce208f872012-03-07 20:42:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]cf3ac3972010-12-22 20:02:292// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]797c3552011-03-17 00:26:185#include "content/common/font_config_ipc_linux.h"
[email protected]cf3ac3972010-12-22 20:02:296
7#include <errno.h>
[email protected]cf3ac3972010-12-22 20:02:298#include <fcntl.h>
[email protected]bf4089062013-03-18 21:01:339#include <sys/mman.h>
[email protected]cf3ac3972010-12-22 20:02:2910#include <sys/socket.h>
[email protected]bf4089062013-03-18 21:01:3311#include <sys/stat.h>
[email protected]cf3ac3972010-12-22 20:02:2912#include <sys/uio.h>
[email protected]8c89c592013-01-18 10:34:2913#include <unistd.h>
[email protected]cf3ac3972010-12-22 20:02:2914
[email protected]6a1048ab2013-08-03 08:03:5115#include "base/debug/trace_event.h"
[email protected]bf4089062013-03-18 21:01:3316#include "base/file_util.h"
[email protected]cf3ac3972010-12-22 20:02:2917#include "base/pickle.h"
[email protected]8c89c592013-01-18 10:34:2918#include "base/posix/unix_domain_socket_linux.h"
[email protected]8e4e8f5f2013-06-06 21:33:5919#include "skia/ext/refptr.h"
[email protected]9628e0d2013-03-12 13:11:5420#include "skia/ext/skia_utils_base.h"
[email protected]8e4e8f5f2013-06-06 21:33:5921#include "third_party/skia/include/core/SkData.h"
[email protected]9628e0d2013-03-12 13:11:5422#include "third_party/skia/include/core/SkStream.h"
[email protected]cf3ac3972010-12-22 20:02:2923
[email protected]130757672012-10-24 00:26:1924namespace content {
25
[email protected]bf4089062013-03-18 21:01:3326// Return a stream from the file descriptor, or NULL on failure.
27SkStream* StreamFromFD(int fd) {
[email protected]8e4e8f5f2013-06-06 21:33:5928 skia::RefPtr<SkData> data = skia::AdoptRef(SkData::NewFromFD(fd));
29 if (!data) {
[email protected]bf4089062013-03-18 21:01:3330 return NULL;
[email protected]8e4e8f5f2013-06-06 21:33:5931 }
32 return new SkMemoryStream(data.get());
[email protected]bf4089062013-03-18 21:01:3333}
34
35void CloseFD(int fd) {
36 int err = HANDLE_EINTR(close(fd));
37 DCHECK(!err);
38}
39
[email protected]cf3ac3972010-12-22 20:02:2940FontConfigIPC::FontConfigIPC(int fd)
41 : fd_(fd) {
42}
43
44FontConfigIPC::~FontConfigIPC() {
[email protected]bf4089062013-03-18 21:01:3345 CloseFD(fd_);
[email protected]cf3ac3972010-12-22 20:02:2946}
47
[email protected]9628e0d2013-03-12 13:11:5448bool FontConfigIPC::matchFamilyName(const char familyName[],
49 SkTypeface::Style requestedStyle,
50 FontIdentity* outFontIdentity,
51 SkString* outFamilyName,
52 SkTypeface::Style* outStyle) {
[email protected]6a1048ab2013-08-03 08:03:5153 TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName");
[email protected]9628e0d2013-03-12 13:11:5454 size_t familyNameLen = familyName ? strlen(familyName) : 0;
55 if (familyNameLen > kMaxFontFamilyLength)
[email protected]cf3ac3972010-12-22 20:02:2956 return false;
57
58 Pickle request;
59 request.WriteInt(METHOD_MATCH);
[email protected]9628e0d2013-03-12 13:11:5460 request.WriteData(familyName, familyNameLen);
61 request.WriteUInt32(requestedStyle);
[email protected]cf3ac3972010-12-22 20:02:2962
[email protected]9628e0d2013-03-12 13:11:5463 uint8_t reply_buf[2048];
[email protected]cf3ac3972010-12-22 20:02:2964 const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf,
65 sizeof(reply_buf), NULL,
66 request);
67 if (r == -1)
68 return false;
69
70 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
[email protected]ce208f872012-03-07 20:42:5671 PickleIterator iter(reply);
[email protected]cf3ac3972010-12-22 20:02:2972 bool result;
73 if (!reply.ReadBool(&iter, &result))
74 return false;
75 if (!result)
76 return false;
77
[email protected]9628e0d2013-03-12 13:11:5478 SkString reply_family;
79 FontIdentity reply_identity;
80 uint32_t reply_style;
81 if (!skia::ReadSkString(reply, &iter, &reply_family) ||
82 !skia::ReadSkFontIdentity(reply, &iter, &reply_identity) ||
83 !reply.ReadUInt32(&iter, &reply_style)) {
[email protected]cf3ac3972010-12-22 20:02:2984 return false;
85 }
86
[email protected]9628e0d2013-03-12 13:11:5487 if (outFontIdentity)
88 *outFontIdentity = reply_identity;
89 if (outFamilyName)
90 *outFamilyName = reply_family;
91 if (outStyle)
92 *outStyle = static_cast<SkTypeface::Style>(reply_style);
[email protected]cf3ac3972010-12-22 20:02:2993
94 return true;
95}
96
[email protected]9628e0d2013-03-12 13:11:5497SkStream* FontConfigIPC::openStream(const FontIdentity& identity) {
[email protected]6a1048ab2013-08-03 08:03:5198 TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream");
[email protected]cf3ac3972010-12-22 20:02:2999 Pickle request;
100 request.WriteInt(METHOD_OPEN);
[email protected]9628e0d2013-03-12 13:11:54101 request.WriteUInt32(identity.fID);
[email protected]cf3ac3972010-12-22 20:02:29102
103 int result_fd = -1;
104 uint8_t reply_buf[256];
105 const ssize_t r = UnixDomainSocket::SendRecvMsg(fd_, reply_buf,
106 sizeof(reply_buf),
107 &result_fd, request);
108
109 if (r == -1)
[email protected]9628e0d2013-03-12 13:11:54110 return NULL;
[email protected]cf3ac3972010-12-22 20:02:29111
112 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
113 bool result;
[email protected]ce208f872012-03-07 20:42:56114 PickleIterator iter(reply);
[email protected]cf3ac3972010-12-22 20:02:29115 if (!reply.ReadBool(&iter, &result) ||
116 !result) {
117 if (result_fd)
[email protected]bf4089062013-03-18 21:01:33118 CloseFD(result_fd);
[email protected]9628e0d2013-03-12 13:11:54119 return NULL;
[email protected]cf3ac3972010-12-22 20:02:29120 }
121
[email protected]bf4089062013-03-18 21:01:33122 SkStream* stream = StreamFromFD(result_fd);
123 CloseFD(result_fd);
124 return stream;
[email protected]cf3ac3972010-12-22 20:02:29125}
[email protected]130757672012-10-24 00:26:19126
127} // namespace content
[email protected]bf4089062013-03-18 21:01:33128