• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/common/font_config_ipc_linux.h"
6 
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <sys/mman.h>
10 #include <sys/socket.h>
11 #include <sys/stat.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14 
15 #include "base/debug/trace_event.h"
16 #include "base/file_util.h"
17 #include "base/pickle.h"
18 #include "base/posix/unix_domain_socket_linux.h"
19 #include "skia/ext/refptr.h"
20 #include "skia/ext/skia_utils_base.h"
21 #include "third_party/skia/include/core/SkData.h"
22 #include "third_party/skia/include/core/SkStream.h"
23 
24 namespace content {
25 
26 // Return a stream from the file descriptor, or NULL on failure.
StreamFromFD(int fd)27 SkStream* StreamFromFD(int fd) {
28   skia::RefPtr<SkData> data = skia::AdoptRef(SkData::NewFromFD(fd));
29   if (!data) {
30     return NULL;
31   }
32   return new SkMemoryStream(data.get());
33 }
34 
CloseFD(int fd)35 void CloseFD(int fd) {
36   int err = IGNORE_EINTR(close(fd));
37   DCHECK(!err);
38 }
39 
FontConfigIPC(int fd)40 FontConfigIPC::FontConfigIPC(int fd)
41     : fd_(fd) {
42 }
43 
~FontConfigIPC()44 FontConfigIPC::~FontConfigIPC() {
45   CloseFD(fd_);
46 }
47 
matchFamilyName(const char familyName[],SkTypeface::Style requestedStyle,FontIdentity * outFontIdentity,SkString * outFamilyName,SkTypeface::Style * outStyle)48 bool FontConfigIPC::matchFamilyName(const char familyName[],
49                                     SkTypeface::Style requestedStyle,
50                                     FontIdentity* outFontIdentity,
51                                     SkString* outFamilyName,
52                                     SkTypeface::Style* outStyle) {
53   TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName");
54   size_t familyNameLen = familyName ? strlen(familyName) : 0;
55   if (familyNameLen > kMaxFontFamilyLength)
56     return false;
57 
58   Pickle request;
59   request.WriteInt(METHOD_MATCH);
60   request.WriteData(familyName, familyNameLen);
61   request.WriteUInt32(requestedStyle);
62 
63   uint8_t reply_buf[2048];
64   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);
71   PickleIterator iter(reply);
72   bool result;
73   if (!reply.ReadBool(&iter, &result))
74     return false;
75   if (!result)
76     return false;
77 
78   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)) {
84     return false;
85   }
86 
87   if (outFontIdentity)
88     *outFontIdentity = reply_identity;
89   if (outFamilyName)
90     *outFamilyName = reply_family;
91   if (outStyle)
92     *outStyle = static_cast<SkTypeface::Style>(reply_style);
93 
94   return true;
95 }
96 
openStream(const FontIdentity & identity)97 SkStream* FontConfigIPC::openStream(const FontIdentity& identity) {
98   TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream");
99   Pickle request;
100   request.WriteInt(METHOD_OPEN);
101   request.WriteUInt32(identity.fID);
102 
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)
110     return NULL;
111 
112   Pickle reply(reinterpret_cast<char*>(reply_buf), r);
113   bool result;
114   PickleIterator iter(reply);
115   if (!reply.ReadBool(&iter, &result) ||
116       !result) {
117     if (result_fd)
118       CloseFD(result_fd);
119     return NULL;
120   }
121 
122   SkStream* stream = StreamFromFD(result_fd);
123   CloseFD(result_fd);
124   return stream;
125 }
126 
127 }  // namespace content
128 
129