1 // Copyright (c) 2012 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 #ifndef PDF_OUT_OF_PROCESS_INSTANCE_H_ 6 #define PDF_OUT_OF_PROCESS_INSTANCE_H_ 7 8 #include <queue> 9 #include <set> 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include "base/memory/scoped_ptr.h" 15 #include "pdf/paint_manager.h" 16 #include "pdf/pdf_engine.h" 17 #include "pdf/preview_mode_client.h" 18 19 #include "ppapi/c/private/ppb_pdf.h" 20 #include "ppapi/cpp/dev/printing_dev.h" 21 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" 22 #include "ppapi/cpp/dev/selection_dev.h" 23 #include "ppapi/cpp/graphics_2d.h" 24 #include "ppapi/cpp/image_data.h" 25 #include "ppapi/cpp/input_event.h" 26 #include "ppapi/cpp/instance.h" 27 #include "ppapi/cpp/private/find_private.h" 28 #include "ppapi/cpp/private/uma_private.h" 29 #include "ppapi/cpp/private/var_private.h" 30 #include "ppapi/cpp/url_loader.h" 31 #include "ppapi/utility/completion_callback_factory.h" 32 33 namespace pp { 34 class TextInput_Dev; 35 } 36 37 namespace chrome_pdf { 38 39 class OutOfProcessInstance : public pp::Instance, 40 public pp::Find_Private, 41 public pp::Printing_Dev, 42 public pp::Selection_Dev, 43 public PaintManager::Client, 44 public PDFEngine::Client, 45 public PreviewModeClient::Client { 46 public: 47 explicit OutOfProcessInstance(PP_Instance instance); 48 virtual ~OutOfProcessInstance(); 49 50 // pp::Instance implementation. 51 virtual bool Init(uint32_t argc, 52 const char* argn[], 53 const char* argv[]) OVERRIDE; 54 virtual void HandleMessage(const pp::Var& message) OVERRIDE; 55 virtual bool HandleInputEvent(const pp::InputEvent& event) OVERRIDE; 56 virtual void DidChangeView(const pp::View& view) OVERRIDE; 57 58 // pp::Find_Private implementation. 59 virtual bool StartFind(const std::string& text, bool case_sensitive) OVERRIDE; 60 virtual void SelectFindResult(bool forward) OVERRIDE; 61 virtual void StopFind() OVERRIDE; 62 63 // pp::PaintManager::Client implementation. 64 virtual void OnPaint(const std::vector<pp::Rect>& paint_rects, 65 std::vector<PaintManager::ReadyRect>* ready, 66 std::vector<pp::Rect>* pending) OVERRIDE; 67 68 // pp::Printing_Dev implementation. 69 virtual uint32_t QuerySupportedPrintOutputFormats() OVERRIDE; 70 virtual int32_t PrintBegin( 71 const PP_PrintSettings_Dev& print_settings) OVERRIDE; 72 virtual pp::Resource PrintPages( 73 const PP_PrintPageNumberRange_Dev* page_ranges, 74 uint32_t page_range_count) OVERRIDE; 75 virtual void PrintEnd() OVERRIDE; 76 virtual bool IsPrintScalingDisabled() OVERRIDE; 77 78 // pp::Private implementation. 79 virtual pp::Var GetLinkAtPosition(const pp::Point& point); 80 81 // PPP_Selection_Dev implementation. 82 virtual pp::Var GetSelectedText(bool html) OVERRIDE; 83 84 void FlushCallback(int32_t result); 85 void DidOpen(int32_t result); 86 void DidOpenPreview(int32_t result); 87 88 // Called when the timer is fired. 89 void OnClientTimerFired(int32_t id); 90 91 // Called to print without re-entrancy issues. 92 void OnPrint(int32_t); 93 94 // PDFEngine::Client implementation. 95 virtual void DocumentSizeUpdated(const pp::Size& size); 96 virtual void Invalidate(const pp::Rect& rect); 97 virtual void Scroll(const pp::Point& point); 98 virtual void ScrollToX(int position); 99 virtual void ScrollToY(int position); 100 virtual void ScrollToPage(int page); 101 virtual void NavigateTo(const std::string& url, bool open_in_new_tab); 102 virtual void UpdateCursor(PP_CursorType_Dev cursor); 103 virtual void UpdateTickMarks(const std::vector<pp::Rect>& tickmarks); 104 virtual void NotifyNumberOfFindResultsChanged(int total, bool final_result); 105 virtual void NotifySelectedFindResultChanged(int current_find_index); 106 virtual void GetDocumentPassword( 107 pp::CompletionCallbackWithOutput<pp::Var> callback); 108 virtual void Alert(const std::string& message); 109 virtual bool Confirm(const std::string& message); 110 virtual std::string Prompt(const std::string& question, 111 const std::string& default_answer); 112 virtual std::string GetURL(); 113 virtual void Email(const std::string& to, 114 const std::string& cc, 115 const std::string& bcc, 116 const std::string& subject, 117 const std::string& body); 118 virtual void Print(); 119 virtual void SubmitForm(const std::string& url, 120 const void* data, 121 int length); 122 virtual std::string ShowFileSelectionDialog(); 123 virtual pp::URLLoader CreateURLLoader(); 124 virtual void ScheduleCallback(int id, int delay_in_ms); 125 virtual void SearchString(const base::char16* string, 126 const base::char16* term, 127 bool case_sensitive, 128 std::vector<SearchStringResult>* results); 129 virtual void DocumentPaintOccurred(); 130 virtual void DocumentLoadComplete(int page_count); 131 virtual void DocumentLoadFailed(); 132 virtual pp::Instance* GetPluginInstance(); 133 virtual void DocumentHasUnsupportedFeature(const std::string& feature); 134 virtual void DocumentLoadProgress(uint32 available, uint32 doc_size); 135 virtual void FormTextFieldFocusChange(bool in_focus); 136 virtual bool IsPrintPreview(); 137 138 // PreviewModeClient::Client implementation. 139 virtual void PreviewDocumentLoadComplete() OVERRIDE; 140 virtual void PreviewDocumentLoadFailed() OVERRIDE; 141 142 // Helper functions for implementing PPP_PDF. 143 void RotateClockwise(); 144 void RotateCounterclockwise(); 145 146 private: 147 void ResetRecentlySentFindUpdate(int32_t); 148 149 // Called whenever the plugin geometry changes to update the location of the 150 // background parts, and notifies the pdf engine. 151 void OnGeometryChanged(double old_zoom, float old_device_scale); 152 153 // Figures out the location of any background rectangles (i.e. those that 154 // aren't painted by the PDF engine). 155 void CalculateBackgroundParts(); 156 157 // Computes document width/height in device pixels, based on current zoom and 158 // device scale 159 int GetDocumentPixelWidth() const; 160 int GetDocumentPixelHeight() const; 161 162 // Draws a rectangle with the specified dimensions and color in our buffer. 163 void FillRect(const pp::Rect& rect, unsigned int color); 164 165 void LoadUrl(const std::string& url); 166 void LoadPreviewUrl(const std::string& url); 167 void LoadUrlInternal(const std::string& url, pp::URLLoader* loader, 168 void (OutOfProcessInstance::* method)(int32_t)); 169 170 // Creates a URL loader and allows it to access all urls, i.e. not just the 171 // frame's origin. 172 pp::URLLoader CreateURLLoaderInternal(); 173 174 // Figure out the initial page to display based on #page=N and #nameddest=foo 175 // in the |url_|. 176 // Returns -1 if there is no valid fragment. The returned value is 0-based, 177 // whereas page=N is 1-based. 178 int GetInitialPage(const std::string& url); 179 180 void FormDidOpen(int32_t result); 181 182 std::string GetLocalizedString(PP_ResourceString id); 183 184 void UserMetricsRecordAction(const std::string& action); 185 186 enum DocumentLoadState { 187 LOAD_STATE_LOADING, 188 LOAD_STATE_COMPLETE, 189 LOAD_STATE_FAILED, 190 }; 191 192 // Set new zoom scale. 193 void SetZoom(double scale); 194 195 // Reduces the document to 1 page and appends |print_preview_page_count_| 196 // blank pages to the document for print preview. 197 void AppendBlankPrintPreviewPages(); 198 199 // Process the preview page data information. |src_url| specifies the preview 200 // page data location. The |src_url| is in the format: 201 // chrome://print/id/page_number/print.pdf 202 // |dst_page_index| specifies the blank page index that needs to be replaced 203 // with the new page data. 204 void ProcessPreviewPageInfo(const std::string& src_url, int dst_page_index); 205 // Load the next available preview page into the blank page. 206 void LoadAvailablePreviewPage(); 207 208 pp::ImageData image_data_; 209 // Used when the plugin is embedded in a page and we have to create the loader 210 // ourself. 211 pp::CompletionCallbackFactory<OutOfProcessInstance> loader_factory_; 212 pp::URLLoader embed_loader_; 213 pp::URLLoader embed_preview_loader_; 214 215 PP_CursorType_Dev cursor_; // The current cursor. 216 217 pp::CompletionCallbackFactory<OutOfProcessInstance> timer_factory_; 218 219 // Size, in pixels, of plugin rectangle. 220 pp::Size plugin_size_; 221 // Size, in DIPs, of plugin rectangle. 222 pp::Size plugin_dip_size_; 223 // Remaining area, in pixels, to render the pdf in after accounting for 224 // horizontal centering. 225 pp::Rect available_area_; 226 // Size of entire document in pixels (i.e. if each page is 800 pixels high and 227 // there are 10 pages, the height will be 8000). 228 pp::Size document_size_; 229 230 double zoom_; // Current zoom factor. 231 232 float device_scale_; // Current device scale factor. 233 bool printing_enabled_; 234 // True if the plugin is full-page. 235 bool full_; 236 237 PaintManager paint_manager_; 238 239 struct BackgroundPart { 240 pp::Rect location; 241 unsigned int color; 242 }; 243 std::vector<BackgroundPart> background_parts_; 244 245 struct PrintSettings { 246 PrintSettings() { 247 Clear(); 248 } 249 void Clear() { 250 is_printing = false; 251 print_pages_called_ = false; 252 memset(&pepper_print_settings, 0, sizeof(pepper_print_settings)); 253 } 254 // This is set to true when PrintBegin is called and false when PrintEnd is 255 // called. 256 bool is_printing; 257 // To know whether this was an actual print operation, so we don't double 258 // count UMA logging. 259 bool print_pages_called_; 260 PP_PrintSettings_Dev pepper_print_settings; 261 }; 262 263 PrintSettings print_settings_; 264 265 scoped_ptr<PDFEngine> engine_; 266 267 // This engine is used to render the individual preview page data. This is 268 // used only in print preview mode. This will use |PreviewModeClient| 269 // interface which has very limited access to the pp::Instance. 270 scoped_ptr<PDFEngine> preview_engine_; 271 272 std::string url_; 273 274 // Used for submitting forms. 275 pp::CompletionCallbackFactory<OutOfProcessInstance> form_factory_; 276 pp::URLLoader form_loader_; 277 278 // Used for printing without re-entrancy issues. 279 pp::CompletionCallbackFactory<OutOfProcessInstance> print_callback_factory_; 280 281 // True if we haven't painted the plugin viewport yet. 282 bool first_paint_; 283 284 DocumentLoadState document_load_state_; 285 DocumentLoadState preview_document_load_state_; 286 287 // JavaScript interface to control this instance. 288 // This wraps a PDFScriptableObject in a pp::Var. 289 pp::VarPrivate instance_object_; 290 291 // A UMA resource for histogram reporting. 292 pp::UMAPrivate uma_; 293 294 // Used so that we only tell the browser once about an unsupported feature, to 295 // avoid the infobar going up more than once. 296 bool told_browser_about_unsupported_feature_; 297 298 // Keeps track of which unsupported features we reported, so we avoid spamming 299 // the stats if a feature shows up many times per document. 300 std::set<std::string> unsupported_features_reported_; 301 302 // Number of pages in print preview mode, 0 if not in print preview mode. 303 int print_preview_page_count_; 304 std::vector<int> print_preview_page_numbers_; 305 306 // Used to manage loaded print preview page information. A |PreviewPageInfo| 307 // consists of data source url string and the page index in the destination 308 // document. 309 typedef std::pair<std::string, int> PreviewPageInfo; 310 std::queue<PreviewPageInfo> preview_pages_info_; 311 312 // Used to signal the browser about focus changes to trigger the OSK. 313 // TODO(abodenha (at) chromium.org) Implement full IME support in the plugin. 314 // http://crbug.com/132565 315 scoped_ptr<pp::TextInput_Dev> text_input_; 316 317 // The last document load progress value sent to the web page. 318 double last_progress_sent_; 319 320 // Whether an update to the number of find results found was sent less than 321 // |kFindResultCooldownMs| milliseconds ago. 322 bool recently_sent_find_update_; 323 324 // The tickmarks. 325 std::vector<pp::Rect> tickmarks_; 326 327 // Whether the plugin has received a viewport changed message. Nothing should 328 // be painted until this is received. 329 bool received_viewport_message_; 330 331 // If true, this means we told the RenderView that we're starting a network 332 // request so that it can start the throbber. We will tell it again once the 333 // document finishes loading. 334 bool did_call_start_loading_; 335 336 // The callback for receiving the password from the page. 337 scoped_ptr<pp::CompletionCallbackWithOutput<pp::Var> > password_callback_; 338 }; 339 340 } // namespace chrome_pdf 341 342 #endif // PDF_OUT_OF_PROCESS_INSTANCE_H_ 343