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 "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 
     20 namespace ppapi {
     21 namespace proxy {
     22 
     23 namespace {
     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.
     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());
     33   return lang;
     34 }
     35 
     36 }  // namespace
     37 
     38 PDFResource::PDFResource(Connection connection, PP_Instance instance)
     39     : PluginResource(connection, instance) {
     40   SendCreate(RENDERER, PpapiHostMsg_PDF_Create());
     41 }
     42 
     43 PDFResource::~PDFResource() {
     44 }
     45 
     46 thunk::PPB_PDF_API* PDFResource::AsPPB_PDF_API() {
     47   return this;
     48 }
     49 
     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),
     54       &localized_string);
     55   if (result != PP_OK)
     56     return PP_MakeUndefined();
     57   return ppapi::StringVar::StringToPPVar(localized_string);
     58 }
     59 
     60 void 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 
    111 void PDFResource::DidStartLoading() {
    112   Post(RENDERER, PpapiHostMsg_PDF_DidStartLoading());
    113 }
    114 
    115 void PDFResource::DidStopLoading() {
    116   Post(RENDERER, PpapiHostMsg_PDF_DidStopLoading());
    117 }
    118 
    119 void PDFResource::SetContentRestriction(int restrictions) {
    120   Post(RENDERER, PpapiHostMsg_PDF_SetContentRestriction(restrictions));
    121 }
    122 
    123 void PDFResource::HistogramPDFPageCount(int count) {
    124   UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
    125 }
    126 
    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()) {
    131     Post(RENDERER,
    132          PpapiHostMsg_PDF_UserMetricsRecordAction(action_str->value()));
    133   }
    134 }
    135 
    136 void PDFResource::HasUnsupportedFeature() {
    137   Post(RENDERER, PpapiHostMsg_PDF_HasUnsupportedFeature());
    138 }
    139 
    140 void PDFResource::Print() {
    141   Post(RENDERER, PpapiHostMsg_PDF_Print());
    142 }
    143 
    144 void PDFResource::SaveAs() {
    145   Post(RENDERER, PpapiHostMsg_PDF_SaveAs());
    146 }
    147 
    148 PP_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 
    162 PP_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 
    190 PP_Resource PDFResource::GetResourceImage(PP_ResourceImage image_id) {
    191   return GetResourceImageForScale(image_id, 1.0f);
    192 }
    193 
    194 PP_Bool PDFResource::IsOutOfProcess() {
    195   return PP_TRUE;
    196 }
    197 
    198 void PDFResource::SetSelectedText(const char* selected_text) {
    199   Post(RENDERER,
    200        PpapiHostMsg_PDF_SetSelectedText(base::UTF8ToUTF16(selected_text)));
    201 }
    202 
    203 void PDFResource::SetLinkUnderCursor(const char* url) {
    204   Post(RENDERER, PpapiHostMsg_PDF_SetLinkUnderCursor(url));
    205 }
    206 
    207 }  // namespace proxy
    208 }  // namespace ppapi
    209