1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/renderer_host/pepper/pepper_truetype_font_host.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/task_runner_util.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/threading/sequenced_worker_pool.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_ppapi_host.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ppapi/c/pp_errors.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ppapi/host/dispatch_host_message.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ppapi/host/ppapi_host.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ppapi/proxy/ppapi_messages.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ppapi::host::HostMessageContext;
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ppapi::host::ReplyMessageContext;
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ppapi::proxy::SerializedTrueTypeFontDesc;
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPepperTrueTypeFontHost::PepperTrueTypeFontHost(
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BrowserPpapiHost* host,
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PP_Instance instance,
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PP_Resource resource,
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const SerializedTrueTypeFontDesc& desc)
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : ResourceHost(host->GetPpapiHost(), instance, resource),
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      initialize_completed_(false),
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      weak_factory_(this) {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  font_ = PepperTrueTypeFont::Create();
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Initialize the font on a blocking pool thread. This must complete before
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // using |font_|.
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SerializedTrueTypeFontDesc* actual_desc =
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new SerializedTrueTypeFontDesc(desc);
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::PostTaskAndReplyWithResult(
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_runner_.get(),
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFont::Initialize, font_, actual_desc),
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFontHost::OnInitializeComplete,
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_factory_.GetWeakPtr(),
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Owned(actual_desc)));
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
48116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPepperTrueTypeFontHost::~PepperTrueTypeFontHost() {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (font_.get()) {
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Release the font on the task runner in case the implementation requires
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // long blocking operations.
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    font_->AddRef();
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PepperTrueTypeFont* raw_font = font_.get();
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    font_ = NULL;
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    task_runner_->ReleaseSoon(FROM_HERE, raw_font);
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint32_t PepperTrueTypeFontHost::OnResourceMessageReceived(
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const IPC::Message& msg,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    HostMessageContext* context) {
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!host()->permissions().HasPermission(ppapi::PERMISSION_DEV))
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return PP_ERROR_FAILED;
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PPAPI_BEGIN_MESSAGE_MAP(PepperTrueTypeFontHost, msg)
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TrueTypeFont_GetTableTags,
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      OnHostMsgGetTableTags)
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TrueTypeFont_GetTable,
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    OnHostMsgGetTable)
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PPAPI_END_MESSAGE_MAP()
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return PP_ERROR_FAILED;
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint32_t PepperTrueTypeFontHost::OnHostMsgGetTableTags(
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    HostMessageContext* context) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!font_.get())
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return PP_ERROR_FAILED;
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Get font data on a thread that allows slow blocking operations.
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<uint32_t>* tags = new std::vector<uint32_t>();
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::PostTaskAndReplyWithResult(
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_runner_.get(),
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFont::GetTableTags, font_, tags),
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFontHost::OnGetTableTagsComplete,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_factory_.GetWeakPtr(),
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Owned(tags),
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 context->MakeReplyMessageContext()));
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return PP_OK_COMPLETIONPENDING;
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint32_t PepperTrueTypeFontHost::OnHostMsgGetTable(HostMessageContext* context,
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  uint32_t table,
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  int32_t offset,
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                  int32_t max_data_length) {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!font_.get())
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return PP_ERROR_FAILED;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (offset < 0 || max_data_length < 0)
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return PP_ERROR_BADARGUMENT;
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Get font data on a thread that allows slow blocking operations.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string* data = new std::string();
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::PostTaskAndReplyWithResult(
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_runner_.get(),
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFont::GetTable,
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 font_,
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 table,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 offset,
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 max_data_length,
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 data),
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&PepperTrueTypeFontHost::OnGetTableComplete,
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 weak_factory_.GetWeakPtr(),
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Owned(data),
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 context->MakeReplyMessageContext()));
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return PP_OK_COMPLETIONPENDING;
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PepperTrueTypeFontHost::OnInitializeComplete(
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SerializedTrueTypeFontDesc* desc,
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int32_t result) {
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!initialize_completed_);
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  initialize_completed_ = true;
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Release the font if there was an error, so future calls will fail.
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (result != PP_OK)
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    font_ = NULL;
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  host()->SendUnsolicitedReply(
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pp_resource(), PpapiPluginMsg_TrueTypeFont_CreateReply(*desc, result));
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PepperTrueTypeFontHost::OnGetTableTagsComplete(
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::vector<uint32_t>* tags,
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ReplyMessageContext reply_context,
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int32_t result) {
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(initialize_completed_);
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // It's possible that Initialize failed and that |font_| is NULL. Check that
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the font implementation doesn't return PP_OK in that case.
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(font_.get() || result != PP_OK);
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  reply_context.params.set_result(result);
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  host()->SendReply(reply_context,
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    PpapiPluginMsg_TrueTypeFont_GetTableTagsReply(*tags));
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PepperTrueTypeFontHost::OnGetTableComplete(
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string* data,
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ReplyMessageContext reply_context,
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int32_t result) {
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(initialize_completed_);
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // It's possible that Initialize failed and that |font_| is NULL. Check that
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the font implementation doesn't return PP_OK in that case.
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(font_.get() || result != PP_OK);
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  reply_context.params.set_result(result);
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  host()->SendReply(reply_context,
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    PpapiPluginMsg_TrueTypeFont_GetTableReply(*data));
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
160