Home | History | Annotate | Download | only in proxy
      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 "ppapi/c/pp_errors.h"
     13 #include "ppapi/c/private/ppb_pdf.h"
     14 #include "ppapi/proxy/ppapi_messages.h"
     15 #include "ppapi/proxy/ppb_image_data_proxy.h"
     16 #include "ppapi/shared_impl/var.h"
     17 #include "third_party/icu/source/i18n/unicode/usearch.h"
     18 
     19 namespace ppapi {
     20 namespace proxy {
     21 
     22 namespace {
     23 
     24 // TODO(raymes): This is just copied from render_thread_impl.cc. We should have
     25 // generic code somewhere to get the locale in the plugin.
     26 std::string GetLocale() {
     27   // The browser process should have passed the locale to the plugin via the
     28   // --lang command line flag.
     29   const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
     30   const std::string& lang = parsed_command_line.GetSwitchValueASCII("lang");
     31   DCHECK(!lang.empty());
     32   return lang;
     33 }
     34 
     35 }  // namespace
     36 
     37 PDFResource::PDFResource(Connection connection, PP_Instance instance)
     38     : PluginResource(connection, instance) {
     39   SendCreate(RENDERER, PpapiHostMsg_PDF_Create());
     40 }
     41 
     42 PDFResource::~PDFResource() {
     43 }
     44 
     45 thunk::PPB_PDF_API* PDFResource::AsPPB_PDF_API() {
     46   return this;
     47 }
     48 
     49 PP_Var PDFResource::GetLocalizedString(PP_ResourceString string_id) {
     50   std::string localized_string;
     51   int32_t result = SyncCall<PpapiPluginMsg_PDF_GetLocalizedStringReply>(
     52       RENDERER, PpapiHostMsg_PDF_GetLocalizedString(string_id),
     53       &localized_string);
     54   if (result != PP_OK)
     55     return PP_MakeUndefined();
     56   return ppapi::StringVar::StringToPPVar(localized_string);
     57 }
     58 
     59 void PDFResource::SearchString(const unsigned short* input_string,
     60                                const unsigned short* input_term,
     61                                bool case_sensitive,
     62                                PP_PrivateFindResult** results, int* count) {
     63   if (locale_.empty())
     64     locale_ = GetLocale();
     65   const char16* string = reinterpret_cast<const char16*>(input_string);
     66   const char16* term = reinterpret_cast<const char16*>(input_term);
     67 
     68   UErrorCode status = U_ZERO_ERROR;
     69   UStringSearch* searcher = usearch_open(term, -1, string, -1, locale_.c_str(),
     70                                          0, &status);
     71   DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
     72          status == U_USING_DEFAULT_WARNING);
     73   UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY;
     74 
     75   UCollator* collator = usearch_getCollator(searcher);
     76   if (ucol_getStrength(collator) != strength) {
     77     ucol_setStrength(collator, strength);
     78     usearch_reset(searcher);
     79   }
     80 
     81   status = U_ZERO_ERROR;
     82   int match_start = usearch_first(searcher, &status);
     83   DCHECK(status == U_ZERO_ERROR);
     84 
     85   std::vector<PP_PrivateFindResult> pp_results;
     86   while (match_start != USEARCH_DONE) {
     87     size_t matched_length = usearch_getMatchedLength(searcher);
     88     PP_PrivateFindResult result;
     89     result.start_index = match_start;
     90     result.length = matched_length;
     91     pp_results.push_back(result);
     92     match_start = usearch_next(searcher, &status);
     93     DCHECK(status == U_ZERO_ERROR);
     94   }
     95 
     96   *count = pp_results.size();
     97   if (*count) {
     98     *results = reinterpret_cast<PP_PrivateFindResult*>(malloc(
     99         *count * sizeof(PP_PrivateFindResult)));
    100     memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult));
    101   } else {
    102     *results = NULL;
    103   }
    104 
    105   usearch_close(searcher);
    106 }
    107 
    108 void PDFResource::DidStartLoading() {
    109   Post(RENDERER, PpapiHostMsg_PDF_DidStartLoading());
    110 }
    111 
    112 void PDFResource::DidStopLoading() {
    113   Post(RENDERER, PpapiHostMsg_PDF_DidStopLoading());
    114 }
    115 
    116 void PDFResource::SetContentRestriction(int restrictions) {
    117   Post(RENDERER, PpapiHostMsg_PDF_SetContentRestriction(restrictions));
    118 }
    119 
    120 void PDFResource::HistogramPDFPageCount(int count) {
    121   UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
    122 }
    123 
    124 void PDFResource::UserMetricsRecordAction(const PP_Var& action) {
    125   scoped_refptr<ppapi::StringVar> action_str(
    126       ppapi::StringVar::FromPPVar(action));
    127   if (action_str.get()) {
    128     Post(RENDERER,
    129          PpapiHostMsg_PDF_UserMetricsRecordAction(action_str->value()));
    130   }
    131 }
    132 
    133 void PDFResource::HasUnsupportedFeature() {
    134   Post(RENDERER, PpapiHostMsg_PDF_HasUnsupportedFeature());
    135 }
    136 
    137 void PDFResource::Print() {
    138   Post(RENDERER, PpapiHostMsg_PDF_Print());
    139 }
    140 
    141 void PDFResource::SaveAs() {
    142   Post(RENDERER, PpapiHostMsg_PDF_SaveAs());
    143 }
    144 
    145 PP_Bool PDFResource::IsFeatureEnabled(PP_PDFFeature feature) {
    146   PP_Bool result = PP_FALSE;
    147   switch (feature) {
    148     case PP_PDFFEATURE_HIDPI:
    149       result = PP_TRUE;
    150       break;
    151     case PP_PDFFEATURE_PRINTING:
    152       // TODO(raymes): Use PrintWebViewHelper::IsPrintingEnabled.
    153       result = PP_FALSE;
    154       break;
    155   }
    156   return result;
    157 }
    158 
    159 PP_Resource PDFResource::GetResourceImageForScale(PP_ResourceImage image_id,
    160                                                   float scale) {
    161   IPC::Message reply;
    162   ResourceMessageReplyParams reply_params;
    163   int32_t result = GenericSyncCall(
    164       RENDERER, PpapiHostMsg_PDF_GetResourceImage(image_id, scale), &reply,
    165       &reply_params);
    166   if (result != PP_OK)
    167     return 0;
    168 
    169   HostResource resource;
    170   PP_ImageDataDesc image_desc;
    171   if (!UnpackMessage<PpapiPluginMsg_PDF_GetResourceImageReply>(
    172       reply, &resource, &image_desc)) {
    173     return 0;
    174   }
    175 
    176   if (resource.is_null())
    177     return 0;
    178   if (!PPB_ImageData_Shared::IsImageDataDescValid(image_desc))
    179     return 0;
    180 
    181   base::SharedMemoryHandle handle;
    182   if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &handle))
    183     return 0;
    184   return (new SimpleImageData(resource, image_desc, handle))->GetReference();
    185 }
    186 
    187 PP_Resource PDFResource::GetResourceImage(PP_ResourceImage image_id) {
    188   return GetResourceImageForScale(image_id, 1.0f);
    189 }
    190 
    191 PP_Bool PDFResource::IsOutOfProcess() {
    192   return PP_TRUE;
    193 }
    194 
    195 }  // namespace proxy
    196 }  // namespace ppapi
    197