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 "ppapi/c/pp_errors.h"
14 #include "ppapi/c/private/ppb_pdf.h"
15 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/proxy/ppb_image_data_proxy.h"
17 #include "ppapi/shared_impl/var.h"
18 #include "third_party/icu/source/i18n/unicode/usearch.h"
25 // TODO(raymes): This is just copied from render_thread_impl.cc. We should have
26 // generic code somewhere to get the locale in the plugin.
27 std::string GetLocale() {
28 // The browser process should have passed the locale to the plugin via the
29 // --lang command line flag.
30 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
31 const std::string& lang = parsed_command_line.GetSwitchValueASCII("lang");
32 DCHECK(!lang.empty());
38 PDFResource::PDFResource(Connection connection, PP_Instance instance)
39 : PluginResource(connection, instance) {
40 SendCreate(RENDERER, PpapiHostMsg_PDF_Create());
43 PDFResource::~PDFResource() {
46 thunk::PPB_PDF_API* PDFResource::AsPPB_PDF_API() {
50 PP_Var PDFResource::GetLocalizedString(PP_ResourceString string_id) {
51 std::string localized_string;
52 int32_t result = SyncCall<PpapiPluginMsg_PDF_GetLocalizedStringReply>(
53 RENDERER, PpapiHostMsg_PDF_GetLocalizedString(string_id),
56 return PP_MakeUndefined();
57 return ppapi::StringVar::StringToPPVar(localized_string);
60 void PDFResource::SearchString(const unsigned short* input_string,
61 const unsigned short* input_term,
63 PP_PrivateFindResult** results, int* count) {
65 locale_ = GetLocale();
66 const base::char16* string =
67 reinterpret_cast<const base::char16*>(input_string);
68 const base::char16* term =
69 reinterpret_cast<const base::char16*>(input_term);
71 UErrorCode status = U_ZERO_ERROR;
72 UStringSearch* searcher = usearch_open(term, -1, string, -1, locale_.c_str(),
74 DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
75 status == U_USING_DEFAULT_WARNING);
76 UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY;
78 UCollator* collator = usearch_getCollator(searcher);
79 if (ucol_getStrength(collator) != strength) {
80 ucol_setStrength(collator, strength);
81 usearch_reset(searcher);
84 status = U_ZERO_ERROR;
85 int match_start = usearch_first(searcher, &status);
86 DCHECK(status == U_ZERO_ERROR);
88 std::vector<PP_PrivateFindResult> pp_results;
89 while (match_start != USEARCH_DONE) {
90 size_t matched_length = usearch_getMatchedLength(searcher);
91 PP_PrivateFindResult result;
92 result.start_index = match_start;
93 result.length = matched_length;
94 pp_results.push_back(result);
95 match_start = usearch_next(searcher, &status);
96 DCHECK(status == U_ZERO_ERROR);
99 *count = pp_results.size();
101 *results = reinterpret_cast<PP_PrivateFindResult*>(malloc(
102 *count * sizeof(PP_PrivateFindResult)));
103 memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult));
108 usearch_close(searcher);
111 void PDFResource::DidStartLoading() {
112 Post(RENDERER, PpapiHostMsg_PDF_DidStartLoading());
115 void PDFResource::DidStopLoading() {
116 Post(RENDERER, PpapiHostMsg_PDF_DidStopLoading());
119 void PDFResource::SetContentRestriction(int restrictions) {
120 Post(RENDERER, PpapiHostMsg_PDF_SetContentRestriction(restrictions));
123 void PDFResource::HistogramPDFPageCount(int count) {
124 UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
127 void PDFResource::UserMetricsRecordAction(const PP_Var& action) {
128 scoped_refptr<ppapi::StringVar> action_str(
129 ppapi::StringVar::FromPPVar(action));
130 if (action_str.get()) {
132 PpapiHostMsg_PDF_UserMetricsRecordAction(action_str->value()));
136 void PDFResource::HasUnsupportedFeature() {
137 Post(RENDERER, PpapiHostMsg_PDF_HasUnsupportedFeature());
140 void PDFResource::Print() {
141 Post(RENDERER, PpapiHostMsg_PDF_Print());
144 void PDFResource::SaveAs() {
145 Post(RENDERER, PpapiHostMsg_PDF_SaveAs());
148 PP_Bool PDFResource::IsFeatureEnabled(PP_PDFFeature feature) {
149 PP_Bool result = PP_FALSE;
151 case PP_PDFFEATURE_HIDPI:
154 case PP_PDFFEATURE_PRINTING:
155 // TODO(raymes): Use PrintWebViewHelper::IsPrintingEnabled.
162 PP_Resource PDFResource::GetResourceImageForScale(PP_ResourceImage image_id,
165 ResourceMessageReplyParams reply_params;
166 int32_t result = GenericSyncCall(
167 RENDERER, PpapiHostMsg_PDF_GetResourceImage(image_id, scale), &reply,
172 HostResource resource;
173 PP_ImageDataDesc image_desc;
174 if (!UnpackMessage<PpapiPluginMsg_PDF_GetResourceImageReply>(
175 reply, &resource, &image_desc)) {
179 if (resource.is_null())
181 if (!PPB_ImageData_Shared::IsImageDataDescValid(image_desc))
184 base::SharedMemoryHandle handle;
185 if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &handle))
187 return (new SimpleImageData(resource, image_desc, handle))->GetReference();
190 PP_Resource PDFResource::GetResourceImage(PP_ResourceImage image_id) {
191 return GetResourceImageForScale(image_id, 1.0f);
194 PP_Bool PDFResource::IsOutOfProcess() {
198 void PDFResource::SetSelectedText(const char* selected_text) {
200 PpapiHostMsg_PDF_SetSelectedText(base::UTF8ToUTF16(selected_text)));
203 void PDFResource::SetLinkUnderCursor(const char* url) {
204 Post(RENDERER, PpapiHostMsg_PDF_SetLinkUnderCursor(url));