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