Check if document was opened during testing.
[pdfium.git] / testing / embedder_test.cpp
1 // Copyright (c) 2015 PDFium 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 "embedder_test.h"
6
7 #include <limits.h>
8
9 #include <list>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "../public/fpdf_text.h"
15 #include "../public/fpdfview.h"
16 #include "test_support.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18
19 #ifdef PDF_ENABLE_V8
20 #include "v8/include/libplatform/libplatform.h"
21 #include "v8/include/v8.h"
22 #endif  // PDF_ENABLE_V8
23
24 namespace {
25 const char* g_exe_path_ = nullptr;
26 }  // namespace
27
28 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) {
29   return true;
30 }
31
32 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {}
33
34 EmbedderTest::EmbedderTest()
35     : default_delegate_(new EmbedderTest::Delegate()),
36       document_(nullptr),
37       form_handle_(nullptr),
38       avail_(nullptr),
39       external_isolate_(nullptr),
40       loader_(nullptr),
41       file_length_(0),
42       file_contents_(nullptr) {
43   memset(&hints_, 0, sizeof(hints_));
44   memset(&file_access_, 0, sizeof(file_access_));
45   memset(&file_avail_, 0, sizeof(file_avail_));
46   delegate_ = default_delegate_.get();
47 }
48
49 EmbedderTest::~EmbedderTest() {
50 }
51
52 void EmbedderTest::SetUp() {
53 #ifdef PDF_ENABLE_V8
54 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
55   InitializeV8ForPDFium(g_exe_path_, std::string(), &natives_, &snapshot_,
56                         &platform_);
57 #else
58   InitializeV8ForPDFium(&platform_);
59 #endif  // V8_USE_EXTERNAL_STARTUP_DATA
60 #endif  // FPDF_ENABLE_V8
61
62   FPDF_LIBRARY_CONFIG config;
63   config.version = 2;
64   config.m_pUserFontPaths = nullptr;
65   config.m_v8EmbedderSlot = 0;
66   config.m_pIsolate = external_isolate_;
67   FPDF_InitLibraryWithConfig(&config);
68
69   UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(this);
70   memset(info, 0, sizeof(UNSUPPORT_INFO));
71   info->version = 1;
72   info->FSDK_UnSupport_Handler = UnsupportedHandlerTrampoline;
73   FSDK_SetUnSpObjProcessHandler(info);
74 }
75
76 void EmbedderTest::TearDown() {
77   if (document_) {
78     FORM_DoDocumentAAction(form_handle_, FPDFDOC_AACTION_WC);
79     FPDFDOC_ExitFormFillEnvironment(form_handle_);
80     FPDF_CloseDocument(document_);
81   }
82   FPDFAvail_Destroy(avail_);
83   FPDF_DestroyLibrary();
84
85 #ifdef PDF_ENABLE_V8
86   v8::V8::ShutdownPlatform();
87   delete platform_;
88 #endif  // PDF_ENABLE_V8
89
90   delete loader_;
91   free(file_contents_);
92 }
93
94 bool EmbedderTest::OpenDocument(const std::string& filename) {
95   file_contents_ = GetFileContents(filename.c_str(), &file_length_);
96   if (!file_contents_)
97     return false;
98
99   loader_ = new TestLoader(file_contents_, file_length_);
100   file_access_.m_FileLen = static_cast<unsigned long>(file_length_);
101   file_access_.m_GetBlock = TestLoader::GetBlock;
102   file_access_.m_Param = loader_;
103
104   file_avail_.version = 1;
105   file_avail_.IsDataAvail = Is_Data_Avail;
106
107   hints_.version = 1;
108   hints_.AddSegment = Add_Segment;
109
110   avail_ = FPDFAvail_Create(&file_avail_, &file_access_);
111   (void)FPDFAvail_IsDocAvail(avail_, &hints_);
112
113   if (!FPDFAvail_IsLinearized(avail_))
114     document_ = FPDF_LoadCustomDocument(&file_access_, nullptr);
115   else
116     document_ = FPDFAvail_GetDocument(avail_, nullptr);
117
118   if (!document_)
119     return false;
120
121   (void)FPDF_GetDocPermissions(document_);
122   (void)FPDFAvail_IsFormAvail(avail_, &hints_);
123
124   IPDF_JSPLATFORM* platform = static_cast<IPDF_JSPLATFORM*>(this);
125   memset(platform, 0, sizeof(IPDF_JSPLATFORM));
126   platform->version = 2;
127   platform->app_alert = AlertTrampoline;
128
129   FPDF_FORMFILLINFO* formfillinfo = static_cast<FPDF_FORMFILLINFO*>(this);
130   memset(formfillinfo, 0, sizeof(FPDF_FORMFILLINFO));
131   formfillinfo->version = 1;
132   formfillinfo->FFI_SetTimer = SetTimerTrampoline;
133   formfillinfo->FFI_KillTimer = KillTimerTrampoline;
134   formfillinfo->FFI_GetPage = GetPageTrampoline;
135   formfillinfo->m_pJsPlatform = platform;
136
137   form_handle_ = FPDFDOC_InitFormFillEnvironment(document_, formfillinfo);
138   FPDF_SetFormFieldHighlightColor(form_handle_, 0, 0xFFE4DD);
139   FPDF_SetFormFieldHighlightAlpha(form_handle_, 100);
140
141   return true;
142 }
143
144 void EmbedderTest::DoOpenActions() {
145   FORM_DoDocumentJSAction(form_handle_);
146   FORM_DoDocumentOpenAction(form_handle_);
147 }
148
149 int EmbedderTest::GetFirstPageNum() {
150   int first_page = FPDFAvail_GetFirstPageNum(document_);
151   (void)FPDFAvail_IsPageAvail(avail_, first_page, &hints_);
152   return first_page;
153 }
154
155 int EmbedderTest::GetPageCount() {
156   int page_count = FPDF_GetPageCount(document_);
157   for (int i = 0; i < page_count; ++i) {
158     (void)FPDFAvail_IsPageAvail(avail_, i, &hints_);
159   }
160   return page_count;
161 }
162
163 FPDF_PAGE EmbedderTest::LoadPage(int page_number) {
164   FPDF_PAGE page = FPDF_LoadPage(document_, page_number);
165   if (!page) {
166     return nullptr;
167   }
168   FORM_OnAfterLoadPage(page, form_handle_);
169   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_OPEN);
170   return page;
171 }
172
173 FPDF_PAGE EmbedderTest::LoadAndCachePage(int page_number) {
174   FPDF_PAGE page = delegate_->GetPage(form_handle_, document_, page_number);
175   if (!page) {
176     return nullptr;
177   }
178   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_OPEN);
179   return page;
180 }
181
182 FPDF_BITMAP EmbedderTest::RenderPage(FPDF_PAGE page) {
183   int width = static_cast<int>(FPDF_GetPageWidth(page));
184   int height = static_cast<int>(FPDF_GetPageHeight(page));
185   FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);
186   FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
187   FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
188   FPDF_FFLDraw(form_handle_, bitmap, page, 0, 0, width, height, 0, 0);
189   return bitmap;
190 }
191
192 void EmbedderTest::UnloadPage(FPDF_PAGE page) {
193   FORM_DoPageAAction(page, form_handle_, FPDFPAGE_AACTION_CLOSE);
194   FORM_OnBeforeClosePage(page, form_handle_);
195   FPDF_ClosePage(page);
196 }
197
198 FPDF_PAGE EmbedderTest::Delegate::GetPage(FPDF_FORMHANDLE form_handle,
199                                           FPDF_DOCUMENT document,
200                                           int page_index) {
201   auto it = m_pageMap.find(page_index);
202   if (it != m_pageMap.end()) {
203     return it->second;
204   }
205   FPDF_PAGE page = FPDF_LoadPage(document, page_index);
206   if (!page) {
207     return nullptr;
208   }
209   m_pageMap[page_index] = page;
210   FORM_OnAfterLoadPage(page, form_handle);
211   return page;
212 }
213
214 // static
215 void EmbedderTest::UnsupportedHandlerTrampoline(UNSUPPORT_INFO* info,
216                                                 int type) {
217   EmbedderTest* test = static_cast<EmbedderTest*>(info);
218   test->delegate_->UnsupportedHandler(type);
219 }
220
221 // static
222 int EmbedderTest::AlertTrampoline(IPDF_JSPLATFORM* platform,
223                                   FPDF_WIDESTRING message,
224                                   FPDF_WIDESTRING title,
225                                   int type,
226                                   int icon) {
227   EmbedderTest* test = static_cast<EmbedderTest*>(platform);
228   return test->delegate_->Alert(message, title, type, icon);
229 }
230
231 // static
232 int EmbedderTest::SetTimerTrampoline(FPDF_FORMFILLINFO* info,
233                                      int msecs,
234                                      TimerCallback fn) {
235   EmbedderTest* test = static_cast<EmbedderTest*>(info);
236   return test->delegate_->SetTimer(msecs, fn);
237 }
238
239 // static
240 void EmbedderTest::KillTimerTrampoline(FPDF_FORMFILLINFO* info, int id) {
241   EmbedderTest* test = static_cast<EmbedderTest*>(info);
242   return test->delegate_->KillTimer(id);
243 }
244
245 // static
246 FPDF_PAGE EmbedderTest::GetPageTrampoline(FPDF_FORMFILLINFO* info,
247                                           FPDF_DOCUMENT document,
248                                           int page_index) {
249   EmbedderTest* test = static_cast<EmbedderTest*>(info);
250   return test->delegate_->GetPage(test->form_handle(), document, page_index);
251 }
252
253 // Can't use gtest-provided main since we need to stash the path to the
254 // executable in order to find the external V8 binary data files.
255 int main(int argc, char** argv) {
256   g_exe_path_ = argv[0];
257   testing::InitGoogleTest(&argc, argv);
258   testing::InitGoogleMock(&argc, argv);
259   return RUN_ALL_TESTS();
260 }