1 // Copyright (c) 2013 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 "ppapi/proxy/pdf_resource.h"
10 #include "base/command_line.h"
11 #include "base/metrics/histogram.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "gin/v8_initializer.h"
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/c/private/ppb_pdf.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/ppb_image_data_proxy.h"
18 #include "ppapi/shared_impl/var.h"
19 #include "third_party/icu/source/i18n/unicode/usearch.h"
26 // TODO(raymes): This is just copied from render_thread_impl.cc. We should have
27 // generic code somewhere to get the locale in the plugin.
28 std::string
GetLocale() {
29 // The browser process should have passed the locale to the plugin via the
30 // --lang command line flag.
31 const base::CommandLine
& parsed_command_line
=
32 *base::CommandLine::ForCurrentProcess();
33 const std::string
& lang
= parsed_command_line
.GetSwitchValueASCII("lang");
34 DCHECK(!lang
.empty());
40 PDFResource::PDFResource(Connection connection
, PP_Instance instance
)
41 : PluginResource(connection
, instance
) {
42 SendCreate(RENDERER
, PpapiHostMsg_PDF_Create());
45 PDFResource::~PDFResource() {
48 thunk::PPB_PDF_API
* PDFResource::AsPPB_PDF_API() {
52 PP_Var
PDFResource::GetLocalizedString(PP_ResourceString string_id
) {
53 std::string localized_string
;
54 int32_t result
= SyncCall
<PpapiPluginMsg_PDF_GetLocalizedStringReply
>(
55 RENDERER
, PpapiHostMsg_PDF_GetLocalizedString(string_id
),
58 return PP_MakeUndefined();
59 return ppapi::StringVar::StringToPPVar(localized_string
);
62 void PDFResource::SearchString(const unsigned short* input_string
,
63 const unsigned short* input_term
,
65 PP_PrivateFindResult
** results
, int* count
) {
67 locale_
= GetLocale();
68 const base::char16
* string
=
69 reinterpret_cast<const base::char16
*>(input_string
);
70 const base::char16
* term
=
71 reinterpret_cast<const base::char16
*>(input_term
);
73 UErrorCode status
= U_ZERO_ERROR
;
74 UStringSearch
* searcher
= usearch_open(term
, -1, string
, -1, locale_
.c_str(),
76 DCHECK(status
== U_ZERO_ERROR
|| status
== U_USING_FALLBACK_WARNING
||
77 status
== U_USING_DEFAULT_WARNING
);
78 UCollationStrength strength
= case_sensitive
? UCOL_TERTIARY
: UCOL_PRIMARY
;
80 UCollator
* collator
= usearch_getCollator(searcher
);
81 if (ucol_getStrength(collator
) != strength
) {
82 ucol_setStrength(collator
, strength
);
83 usearch_reset(searcher
);
86 status
= U_ZERO_ERROR
;
87 int match_start
= usearch_first(searcher
, &status
);
88 DCHECK(status
== U_ZERO_ERROR
);
90 std::vector
<PP_PrivateFindResult
> pp_results
;
91 while (match_start
!= USEARCH_DONE
) {
92 int32_t matched_length
= usearch_getMatchedLength(searcher
);
93 PP_PrivateFindResult result
;
94 result
.start_index
= match_start
;
95 result
.length
= matched_length
;
96 pp_results
.push_back(result
);
97 match_start
= usearch_next(searcher
, &status
);
98 DCHECK(status
== U_ZERO_ERROR
);
101 if (pp_results
.empty() ||
102 pp_results
.size() > std::numeric_limits
<uint32_t>::max() ||
103 pp_results
.size() > SIZE_MAX
/ sizeof(PP_PrivateFindResult
)) {
107 *count
= static_cast<uint32_t>(pp_results
.size());
108 const size_t result_size
= pp_results
.size() * sizeof(PP_PrivateFindResult
);
109 *results
= reinterpret_cast<PP_PrivateFindResult
*>(malloc(result_size
));
110 memcpy(*results
, &pp_results
[0], result_size
);
113 usearch_close(searcher
);
116 void PDFResource::DidStartLoading() {
117 Post(RENDERER
, PpapiHostMsg_PDF_DidStartLoading());
120 void PDFResource::DidStopLoading() {
121 Post(RENDERER
, PpapiHostMsg_PDF_DidStopLoading());
124 void PDFResource::SetContentRestriction(int restrictions
) {
125 Post(RENDERER
, PpapiHostMsg_PDF_SetContentRestriction(restrictions
));
128 void PDFResource::HistogramPDFPageCount(int count
) {
129 UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count
);
132 void PDFResource::UserMetricsRecordAction(const PP_Var
& action
) {
133 scoped_refptr
<ppapi::StringVar
> action_str(
134 ppapi::StringVar::FromPPVar(action
));
135 if (action_str
.get()) {
137 PpapiHostMsg_PDF_UserMetricsRecordAction(action_str
->value()));
141 void PDFResource::HasUnsupportedFeature() {
142 Post(RENDERER
, PpapiHostMsg_PDF_HasUnsupportedFeature());
145 void PDFResource::Print() {
146 Post(RENDERER
, PpapiHostMsg_PDF_Print());
149 void PDFResource::SaveAs() {
150 Post(RENDERER
, PpapiHostMsg_PDF_SaveAs());
153 PP_Bool
PDFResource::IsFeatureEnabled(PP_PDFFeature feature
) {
154 PP_Bool result
= PP_FALSE
;
156 case PP_PDFFEATURE_HIDPI
:
159 case PP_PDFFEATURE_PRINTING
:
160 // TODO(raymes): Use PrintWebViewHelper::IsPrintingEnabled.
167 PP_Resource
PDFResource::GetResourceImageForScale(PP_ResourceImage image_id
,
170 ResourceMessageReplyParams reply_params
;
171 int32_t result
= GenericSyncCall(
172 RENDERER
, PpapiHostMsg_PDF_GetResourceImage(image_id
, scale
), &reply
,
177 HostResource resource
;
178 PP_ImageDataDesc image_desc
;
179 if (!UnpackMessage
<PpapiPluginMsg_PDF_GetResourceImageReply
>(
180 reply
, &resource
, &image_desc
)) {
184 if (resource
.is_null())
186 if (!PPB_ImageData_Shared::IsImageDataDescValid(image_desc
))
189 base::SharedMemoryHandle handle
;
190 if (!reply_params
.TakeSharedMemoryHandleAtIndex(0, &handle
))
192 return (new SimpleImageData(resource
, image_desc
, handle
))->GetReference();
195 PP_Resource
PDFResource::GetResourceImage(PP_ResourceImage image_id
) {
196 return GetResourceImageForScale(image_id
, 1.0f
);
199 PP_Bool
PDFResource::IsOutOfProcess() {
203 void PDFResource::SetSelectedText(const char* selected_text
) {
205 PpapiHostMsg_PDF_SetSelectedText(base::UTF8ToUTF16(selected_text
)));
208 void PDFResource::SetLinkUnderCursor(const char* url
) {
209 Post(RENDERER
, PpapiHostMsg_PDF_SetLinkUnderCursor(url
));
212 void PDFResource::GetV8ExternalSnapshotData(const char** natives_data_out
,
213 int* natives_size_out
,
214 const char** snapshot_data_out
,
215 int* snapshot_size_out
) {
216 gin::V8Initializer::GetV8ExternalSnapshotData(
217 natives_data_out
, natives_size_out
, snapshot_data_out
, snapshot_size_out
);