Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / pepper / pepper_truetype_font_host.cc
1 // Copyright 2014 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/browser/renderer_host/pepper/pepper_truetype_font_host.h"
6
7 #include "base/bind.h"
8 #include "base/task_runner_util.h"
9 #include "base/threading/sequenced_worker_pool.h"
10 #include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
11 #include "content/public/browser/browser_ppapi_host.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/host/dispatch_host_message.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17
18 using ppapi::host::HostMessageContext;
19 using ppapi::host::ReplyMessageContext;
20 using ppapi::proxy::SerializedTrueTypeFontDesc;
21
22 namespace content {
23
24 PepperTrueTypeFontHost::PepperTrueTypeFontHost(
25     BrowserPpapiHost* host,
26     PP_Instance instance,
27     PP_Resource resource,
28     const SerializedTrueTypeFontDesc& desc)
29     : ResourceHost(host->GetPpapiHost(), instance, resource),
30       initialize_completed_(false),
31       weak_factory_(this) {
32   font_ = PepperTrueTypeFont::Create();
33   // Initialize the font on a blocking pool thread. This must complete before
34   // using |font_|.
35   base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
36   task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
37   SerializedTrueTypeFontDesc* actual_desc =
38       new SerializedTrueTypeFontDesc(desc);
39   base::PostTaskAndReplyWithResult(
40       task_runner_.get(),
41       FROM_HERE,
42       base::Bind(&PepperTrueTypeFont::Initialize, font_, actual_desc),
43       base::Bind(&PepperTrueTypeFontHost::OnInitializeComplete,
44                  weak_factory_.GetWeakPtr(),
45                  base::Owned(actual_desc)));
46 }
47
48 PepperTrueTypeFontHost::~PepperTrueTypeFontHost() {
49   if (font_.get()) {
50     // Release the font on the task runner in case the implementation requires
51     // long blocking operations.
52     font_->AddRef();
53     PepperTrueTypeFont* raw_font = font_.get();
54     font_ = NULL;
55     task_runner_->ReleaseSoon(FROM_HERE, raw_font);
56   }
57 }
58
59 int32_t PepperTrueTypeFontHost::OnResourceMessageReceived(
60     const IPC::Message& msg,
61     HostMessageContext* context) {
62   if (!host()->permissions().HasPermission(ppapi::PERMISSION_DEV))
63     return PP_ERROR_FAILED;
64
65   PPAPI_BEGIN_MESSAGE_MAP(PepperTrueTypeFontHost, msg)
66   PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TrueTypeFont_GetTableTags,
67                                       OnHostMsgGetTableTags)
68   PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TrueTypeFont_GetTable,
69                                     OnHostMsgGetTable)
70   PPAPI_END_MESSAGE_MAP()
71   return PP_ERROR_FAILED;
72 }
73
74 int32_t PepperTrueTypeFontHost::OnHostMsgGetTableTags(
75     HostMessageContext* context) {
76   if (!font_.get())
77     return PP_ERROR_FAILED;
78
79   // Get font data on a thread that allows slow blocking operations.
80   std::vector<uint32_t>* tags = new std::vector<uint32_t>();
81   base::PostTaskAndReplyWithResult(
82       task_runner_.get(),
83       FROM_HERE,
84       base::Bind(&PepperTrueTypeFont::GetTableTags, font_, tags),
85       base::Bind(&PepperTrueTypeFontHost::OnGetTableTagsComplete,
86                  weak_factory_.GetWeakPtr(),
87                  base::Owned(tags),
88                  context->MakeReplyMessageContext()));
89
90   return PP_OK_COMPLETIONPENDING;
91 }
92
93 int32_t PepperTrueTypeFontHost::OnHostMsgGetTable(HostMessageContext* context,
94                                                   uint32_t table,
95                                                   int32_t offset,
96                                                   int32_t max_data_length) {
97   if (!font_.get())
98     return PP_ERROR_FAILED;
99   if (offset < 0 || max_data_length < 0)
100     return PP_ERROR_BADARGUMENT;
101
102   // Get font data on a thread that allows slow blocking operations.
103   std::string* data = new std::string();
104   base::PostTaskAndReplyWithResult(
105       task_runner_.get(),
106       FROM_HERE,
107       base::Bind(&PepperTrueTypeFont::GetTable,
108                  font_,
109                  table,
110                  offset,
111                  max_data_length,
112                  data),
113       base::Bind(&PepperTrueTypeFontHost::OnGetTableComplete,
114                  weak_factory_.GetWeakPtr(),
115                  base::Owned(data),
116                  context->MakeReplyMessageContext()));
117
118   return PP_OK_COMPLETIONPENDING;
119 }
120
121 void PepperTrueTypeFontHost::OnInitializeComplete(
122     SerializedTrueTypeFontDesc* desc,
123     int32_t result) {
124   DCHECK(!initialize_completed_);
125   initialize_completed_ = true;
126   // Release the font if there was an error, so future calls will fail.
127   if (result != PP_OK)
128     font_ = NULL;
129   host()->SendUnsolicitedReply(
130       pp_resource(), PpapiPluginMsg_TrueTypeFont_CreateReply(*desc, result));
131 }
132
133 void PepperTrueTypeFontHost::OnGetTableTagsComplete(
134     std::vector<uint32_t>* tags,
135     ReplyMessageContext reply_context,
136     int32_t result) {
137   DCHECK(initialize_completed_);
138   // It's possible that Initialize failed and that |font_| is NULL. Check that
139   // the font implementation doesn't return PP_OK in that case.
140   DCHECK(font_.get() || result != PP_OK);
141   reply_context.params.set_result(result);
142   host()->SendReply(reply_context,
143                     PpapiPluginMsg_TrueTypeFont_GetTableTagsReply(*tags));
144 }
145
146 void PepperTrueTypeFontHost::OnGetTableComplete(
147     std::string* data,
148     ReplyMessageContext reply_context,
149     int32_t result) {
150   DCHECK(initialize_completed_);
151   // It's possible that Initialize failed and that |font_| is NULL. Check that
152   // the font implementation doesn't return PP_OK in that case.
153   DCHECK(font_.get() || result != PP_OK);
154   reply_context.params.set_result(result);
155   host()->SendReply(reply_context,
156                     PpapiPluginMsg_TrueTypeFont_GetTableReply(*data));
157 }
158
159 }  // namespace content