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. 4 5#include "ppapi/proxy/pdf_resource.h" 6 7#include <stdlib.h> 8#include <string.h> 9 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" 19 20namespace ppapi { 21namespace proxy { 22 23namespace { 24 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. 27std::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()); 33 return lang; 34} 35 36} // namespace 37 38PDFResource::PDFResource(Connection connection, PP_Instance instance) 39 : PluginResource(connection, instance) { 40 SendCreate(RENDERER, PpapiHostMsg_PDF_Create()); 41} 42 43PDFResource::~PDFResource() { 44} 45 46thunk::PPB_PDF_API* PDFResource::AsPPB_PDF_API() { 47 return this; 48} 49 50PP_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), 54 &localized_string); 55 if (result != PP_OK) 56 return PP_MakeUndefined(); 57 return ppapi::StringVar::StringToPPVar(localized_string); 58} 59 60void PDFResource::SearchString(const unsigned short* input_string, 61 const unsigned short* input_term, 62 bool case_sensitive, 63 PP_PrivateFindResult** results, int* count) { 64 if (locale_.empty()) 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); 70 71 UErrorCode status = U_ZERO_ERROR; 72 UStringSearch* searcher = usearch_open(term, -1, string, -1, locale_.c_str(), 73 0, &status); 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; 77 78 UCollator* collator = usearch_getCollator(searcher); 79 if (ucol_getStrength(collator) != strength) { 80 ucol_setStrength(collator, strength); 81 usearch_reset(searcher); 82 } 83 84 status = U_ZERO_ERROR; 85 int match_start = usearch_first(searcher, &status); 86 DCHECK(status == U_ZERO_ERROR); 87 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); 97 } 98 99 *count = pp_results.size(); 100 if (*count) { 101 *results = reinterpret_cast<PP_PrivateFindResult*>(malloc( 102 *count * sizeof(PP_PrivateFindResult))); 103 memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult)); 104 } else { 105 *results = NULL; 106 } 107 108 usearch_close(searcher); 109} 110 111void PDFResource::DidStartLoading() { 112 Post(RENDERER, PpapiHostMsg_PDF_DidStartLoading()); 113} 114 115void PDFResource::DidStopLoading() { 116 Post(RENDERER, PpapiHostMsg_PDF_DidStopLoading()); 117} 118 119void PDFResource::SetContentRestriction(int restrictions) { 120 Post(RENDERER, PpapiHostMsg_PDF_SetContentRestriction(restrictions)); 121} 122 123void PDFResource::HistogramPDFPageCount(int count) { 124 UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count); 125} 126 127void PDFResource::UserMetricsRecordAction(const PP_Var& action) { 128 scoped_refptr<ppapi::StringVar> action_str( 129 ppapi::StringVar::FromPPVar(action)); 130 if (action_str.get()) { 131 Post(RENDERER, 132 PpapiHostMsg_PDF_UserMetricsRecordAction(action_str->value())); 133 } 134} 135 136void PDFResource::HasUnsupportedFeature() { 137 Post(RENDERER, PpapiHostMsg_PDF_HasUnsupportedFeature()); 138} 139 140void PDFResource::Print() { 141 Post(RENDERER, PpapiHostMsg_PDF_Print()); 142} 143 144void PDFResource::SaveAs() { 145 Post(RENDERER, PpapiHostMsg_PDF_SaveAs()); 146} 147 148PP_Bool PDFResource::IsFeatureEnabled(PP_PDFFeature feature) { 149 PP_Bool result = PP_FALSE; 150 switch (feature) { 151 case PP_PDFFEATURE_HIDPI: 152 result = PP_TRUE; 153 break; 154 case PP_PDFFEATURE_PRINTING: 155 // TODO(raymes): Use PrintWebViewHelper::IsPrintingEnabled. 156 result = PP_FALSE; 157 break; 158 } 159 return result; 160} 161 162PP_Resource PDFResource::GetResourceImageForScale(PP_ResourceImage image_id, 163 float scale) { 164 IPC::Message reply; 165 ResourceMessageReplyParams reply_params; 166 int32_t result = GenericSyncCall( 167 RENDERER, PpapiHostMsg_PDF_GetResourceImage(image_id, scale), &reply, 168 &reply_params); 169 if (result != PP_OK) 170 return 0; 171 172 HostResource resource; 173 PP_ImageDataDesc image_desc; 174 if (!UnpackMessage<PpapiPluginMsg_PDF_GetResourceImageReply>( 175 reply, &resource, &image_desc)) { 176 return 0; 177 } 178 179 if (resource.is_null()) 180 return 0; 181 if (!PPB_ImageData_Shared::IsImageDataDescValid(image_desc)) 182 return 0; 183 184 base::SharedMemoryHandle handle; 185 if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &handle)) 186 return 0; 187 return (new SimpleImageData(resource, image_desc, handle))->GetReference(); 188} 189 190PP_Resource PDFResource::GetResourceImage(PP_ResourceImage image_id) { 191 return GetResourceImageForScale(image_id, 1.0f); 192} 193 194PP_Bool PDFResource::IsOutOfProcess() { 195 return PP_TRUE; 196} 197 198void PDFResource::SetSelectedText(const char* selected_text) { 199 Post(RENDERER, 200 PpapiHostMsg_PDF_SetSelectedText(base::UTF8ToUTF16(selected_text))); 201} 202 203void PDFResource::SetLinkUnderCursor(const char* url) { 204 Post(RENDERER, PpapiHostMsg_PDF_SetLinkUnderCursor(url)); 205} 206 207} // namespace proxy 208} // namespace ppapi 209