1 // Copyright 2015 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.
5 #include "components/font_service/public/cpp/font_service_thread.h"
8 #include "base/files/file.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "components/font_service/public/cpp/mapped_font_file.h"
11 #include "mojo/message_pump/message_pump_mojo.h"
12 #include "mojo/platform_handle/platform_handle_functions.h"
14 namespace font_service
{
18 const char kFontThreadName
[] = "Font_Proxy_Thread";
21 FontServiceThread::FontServiceThread(FontServicePtr font_service
)
22 : base::Thread(kFontThreadName
),
23 font_service_info_(font_service
.PassInterface().Pass()) {
24 base::Thread::Options options
;
25 options
.message_pump_factory
=
26 base::Bind(&mojo::common::MessagePumpMojo::Create
);
27 StartWithOptions(options
);
30 bool FontServiceThread::MatchFamilyName(
31 const char family_name
[],
32 SkTypeface::Style requested_style
,
33 SkFontConfigInterface::FontIdentity
* out_font_identity
,
34 SkString
* out_family_name
,
35 SkTypeface::Style
* out_style
) {
36 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
38 bool out_valid
= false;
39 // This proxies to the other thread, which proxies to mojo. Only on the reply
40 // from mojo do we return from this.
41 base::WaitableEvent
done_event(false, false);
42 task_runner()->PostTask(
44 base::Bind(&FontServiceThread::MatchFamilyNameImpl
, this, &done_event
,
45 family_name
, requested_style
, &out_valid
, out_font_identity
,
46 out_family_name
, out_style
));
52 scoped_refptr
<MappedFontFile
> FontServiceThread::OpenStream(
53 const SkFontConfigInterface::FontIdentity
& identity
) {
54 DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
56 base::File stream_file
;
57 // This proxies to the other thread, which proxies to mojo. Only on the reply
58 // from mojo do we return from this.
59 base::WaitableEvent
done_event(false, false);
60 task_runner()->PostTask(FROM_HERE
,
61 base::Bind(&FontServiceThread::OpenStreamImpl
, this,
62 &done_event
, &stream_file
, identity
.fID
));
65 if (!stream_file
.IsValid()) {
70 // Converts the file to out internal type.
71 scoped_refptr
<MappedFontFile
> mapped_font_file
=
72 new MappedFontFile(identity
.fID
);
73 if (!mapped_font_file
->Initialize(stream_file
.Pass()))
76 return mapped_font_file
;
79 FontServiceThread::~FontServiceThread() {
83 void FontServiceThread::MatchFamilyNameImpl(
84 base::WaitableEvent
* done_event
,
85 const char family_name
[],
86 SkTypeface::Style requested_style
,
88 SkFontConfigInterface::FontIdentity
* out_font_identity
,
89 SkString
* out_family_name
,
90 SkTypeface::Style
* out_style
) {
91 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
93 font_service_
->MatchFamilyName(
94 mojo::String(family_name
), static_cast<TypefaceStyle
>(requested_style
),
95 base::Bind(&FontServiceThread::OnMatchFamilyNameComplete
, this,
96 done_event
, out_valid
, out_font_identity
, out_family_name
,
100 void FontServiceThread::OnMatchFamilyNameComplete(
101 base::WaitableEvent
* done_event
,
103 SkFontConfigInterface::FontIdentity
* out_font_identity
,
104 SkString
* out_family_name
,
105 SkTypeface::Style
* out_style
,
106 FontIdentityPtr font_identity
,
107 mojo::String family_name
,
108 TypefaceStyle style
) {
109 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
111 *out_valid
= font_identity
;
113 out_font_identity
->fID
= font_identity
->id
;
114 out_font_identity
->fTTCIndex
= font_identity
->ttc_index
;
115 out_font_identity
->fString
= font_identity
->str_representation
.data();
116 // TODO(erg): fStyle isn't set. This is rather odd, however it matches the
117 // behaviour of the current Linux IPC version.
119 *out_family_name
= family_name
.data();
120 *out_style
= static_cast<SkTypeface::Style
>(style
);
123 done_event
->Signal();
126 void FontServiceThread::OpenStreamImpl(base::WaitableEvent
* done_event
,
127 base::File
* output_file
,
128 const uint32_t id_number
) {
129 DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
131 font_service_
->OpenStream(
132 id_number
, base::Bind(&FontServiceThread::OnOpenStreamComplete
, this,
133 done_event
, output_file
));
136 void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent
* done_event
,
137 base::File
* output_file
,
138 mojo::ScopedHandle handle
) {
139 if (handle
.is_valid()) {
140 MojoPlatformHandle platform_handle
;
141 CHECK(MojoExtractPlatformHandle(handle
.release().value(),
142 &platform_handle
) == MOJO_RESULT_OK
);
143 *output_file
= base::File(platform_handle
).Pass();
146 done_event
->Signal();
149 void FontServiceThread::Init() {
150 font_service_
.Bind(font_service_info_
.Pass());
153 void FontServiceThread::CleanUp() {
154 font_service_
.reset();
157 } // namespace internal
158 } // namespace font_service