Home | History | Annotate | Download | only in fpdfsdk
      1 // Copyright 2016 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
      8 
      9 #include <memory>
     10 
     11 #include "core/fpdfapi/parser/cpdf_array.h"
     12 #include "core/fpdfdoc/cpdf_docjsactions.h"
     13 #include "fpdfsdk/cpdfsdk_annothandlermgr.h"
     14 #include "fpdfsdk/cpdfsdk_interform.h"
     15 #include "fpdfsdk/cpdfsdk_pageview.h"
     16 #include "fpdfsdk/cpdfsdk_widget.h"
     17 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
     18 #include "fpdfsdk/fsdk_actionhandler.h"
     19 #include "fpdfsdk/javascript/ijs_runtime.h"
     20 #include "third_party/base/ptr_util.h"
     21 
     22 namespace {
     23 
     24 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken
     25 // since modifying the result would impact |bsUTF16LE|.
     26 FPDF_WIDESTRING AsFPDFWideString(CFX_ByteString* bsUTF16LE) {
     27   return reinterpret_cast<FPDF_WIDESTRING>(
     28       bsUTF16LE->GetBuffer(bsUTF16LE->GetLength()));
     29 }
     30 
     31 }  // namespace
     32 
     33 CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
     34     UnderlyingDocumentType* pDoc,
     35     FPDF_FORMFILLINFO* pFFinfo)
     36     : m_pInfo(pFFinfo),
     37       m_pUnderlyingDoc(pDoc),
     38       m_pSysHandler(new CFX_SystemHandler(this)),
     39       m_bChangeMask(false),
     40       m_bBeingDestroyed(false) {}
     41 
     42 CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
     43   m_bBeingDestroyed = true;
     44   ClearAllFocusedAnnots();
     45 
     46   // |m_PageMap| will try to access |m_pInterForm| when it cleans itself up.
     47   // Make sure it is deleted before |m_pInterForm|.
     48   m_PageMap.clear();
     49 
     50   // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| when it cleans
     51   // itself up. Make sure it is deleted before |m_pFormFiller|.
     52   m_pAnnotHandlerMgr.reset();
     53 
     54   // Must destroy the |m_pFormFiller| before the environment (|this|)
     55   // because any created form widgets hold a pointer to the environment.
     56   // Those widgets may call things like KillTimer() as they are shutdown.
     57   m_pFormFiller.reset();
     58 
     59   if (m_pInfo && m_pInfo->Release)
     60     m_pInfo->Release(m_pInfo);
     61 }
     62 
     63 int CPDFSDK_FormFillEnvironment::JS_appAlert(const FX_WCHAR* Msg,
     64                                              const FX_WCHAR* Title,
     65                                              uint32_t Type,
     66                                              uint32_t Icon) {
     67   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
     68       !m_pInfo->m_pJsPlatform->app_alert) {
     69     return -1;
     70   }
     71   CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
     72   CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
     73   return m_pInfo->m_pJsPlatform->app_alert(
     74       m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsMsg),
     75       AsFPDFWideString(&bsTitle), Type, Icon);
     76 }
     77 
     78 int CPDFSDK_FormFillEnvironment::JS_appResponse(const FX_WCHAR* Question,
     79                                                 const FX_WCHAR* Title,
     80                                                 const FX_WCHAR* Default,
     81                                                 const FX_WCHAR* cLabel,
     82                                                 FPDF_BOOL bPassword,
     83                                                 void* response,
     84                                                 int length) {
     85   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
     86       !m_pInfo->m_pJsPlatform->app_response) {
     87     return -1;
     88   }
     89   CFX_ByteString bsQuestion = CFX_WideString(Question).UTF16LE_Encode();
     90   CFX_ByteString bsTitle = CFX_WideString(Title).UTF16LE_Encode();
     91   CFX_ByteString bsDefault = CFX_WideString(Default).UTF16LE_Encode();
     92   CFX_ByteString bsLabel = CFX_WideString(cLabel).UTF16LE_Encode();
     93   return m_pInfo->m_pJsPlatform->app_response(
     94       m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsQuestion),
     95       AsFPDFWideString(&bsTitle), AsFPDFWideString(&bsDefault),
     96       AsFPDFWideString(&bsLabel), bPassword, response, length);
     97 }
     98 
     99 void CPDFSDK_FormFillEnvironment::JS_appBeep(int nType) {
    100   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    101       !m_pInfo->m_pJsPlatform->app_beep) {
    102     return;
    103   }
    104   m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
    105 }
    106 
    107 CFX_WideString CPDFSDK_FormFillEnvironment::JS_fieldBrowse() {
    108   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    109       !m_pInfo->m_pJsPlatform->Field_browse) {
    110     return CFX_WideString();
    111   }
    112   const int nRequiredLen =
    113       m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0);
    114   if (nRequiredLen <= 0)
    115     return CFX_WideString();
    116 
    117   std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
    118   memset(pBuff.get(), 0, nRequiredLen);
    119   const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse(
    120       m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
    121   if (nActualLen <= 0 || nActualLen > nRequiredLen)
    122     return CFX_WideString();
    123 
    124   return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen));
    125 }
    126 
    127 CFX_WideString CPDFSDK_FormFillEnvironment::JS_docGetFilePath() {
    128   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    129       !m_pInfo->m_pJsPlatform->Doc_getFilePath) {
    130     return CFX_WideString();
    131   }
    132   const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
    133       m_pInfo->m_pJsPlatform, nullptr, 0);
    134   if (nRequiredLen <= 0)
    135     return CFX_WideString();
    136 
    137   std::unique_ptr<char[]> pBuff(new char[nRequiredLen]);
    138   memset(pBuff.get(), 0, nRequiredLen);
    139   const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
    140       m_pInfo->m_pJsPlatform, pBuff.get(), nRequiredLen);
    141   if (nActualLen <= 0 || nActualLen > nRequiredLen)
    142     return CFX_WideString();
    143 
    144   return CFX_WideString::FromLocal(CFX_ByteStringC(pBuff.get(), nActualLen));
    145 }
    146 
    147 void CPDFSDK_FormFillEnvironment::JS_docSubmitForm(void* formData,
    148                                                    int length,
    149                                                    const FX_WCHAR* URL) {
    150   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    151       !m_pInfo->m_pJsPlatform->Doc_submitForm) {
    152     return;
    153   }
    154   CFX_ByteString bsDestination = CFX_WideString(URL).UTF16LE_Encode();
    155   m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform, formData,
    156                                          length,
    157                                          AsFPDFWideString(&bsDestination));
    158 }
    159 
    160 void CPDFSDK_FormFillEnvironment::JS_docmailForm(void* mailData,
    161                                                  int length,
    162                                                  FPDF_BOOL bUI,
    163                                                  const FX_WCHAR* To,
    164                                                  const FX_WCHAR* Subject,
    165                                                  const FX_WCHAR* CC,
    166                                                  const FX_WCHAR* BCC,
    167                                                  const FX_WCHAR* Msg) {
    168   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    169       !m_pInfo->m_pJsPlatform->Doc_mail) {
    170     return;
    171   }
    172   CFX_ByteString bsTo = CFX_WideString(To).UTF16LE_Encode();
    173   CFX_ByteString bsSubject = CFX_WideString(Subject).UTF16LE_Encode();
    174   CFX_ByteString bsCC = CFX_WideString(CC).UTF16LE_Encode();
    175   CFX_ByteString bsBcc = CFX_WideString(BCC).UTF16LE_Encode();
    176   CFX_ByteString bsMsg = CFX_WideString(Msg).UTF16LE_Encode();
    177   m_pInfo->m_pJsPlatform->Doc_mail(
    178       m_pInfo->m_pJsPlatform, mailData, length, bUI, AsFPDFWideString(&bsTo),
    179       AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC),
    180       AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg));
    181 }
    182 
    183 void CPDFSDK_FormFillEnvironment::JS_docprint(FPDF_BOOL bUI,
    184                                               int nStart,
    185                                               int nEnd,
    186                                               FPDF_BOOL bSilent,
    187                                               FPDF_BOOL bShrinkToFit,
    188                                               FPDF_BOOL bPrintAsImage,
    189                                               FPDF_BOOL bReverse,
    190                                               FPDF_BOOL bAnnotations) {
    191   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    192       !m_pInfo->m_pJsPlatform->Doc_print) {
    193     return;
    194   }
    195   m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd,
    196                                     bSilent, bShrinkToFit, bPrintAsImage,
    197                                     bReverse, bAnnotations);
    198 }
    199 
    200 void CPDFSDK_FormFillEnvironment::JS_docgotoPage(int nPageNum) {
    201   if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
    202       !m_pInfo->m_pJsPlatform->Doc_gotoPage) {
    203     return;
    204   }
    205   m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
    206 }
    207 
    208 IJS_Runtime* CPDFSDK_FormFillEnvironment::GetJSRuntime() {
    209   if (!IsJSInitiated())
    210     return nullptr;
    211   if (!m_pJSRuntime)
    212     m_pJSRuntime.reset(IJS_Runtime::Create(this));
    213   return m_pJSRuntime.get();
    214 }
    215 
    216 CPDFSDK_AnnotHandlerMgr* CPDFSDK_FormFillEnvironment::GetAnnotHandlerMgr() {
    217   if (!m_pAnnotHandlerMgr)
    218     m_pAnnotHandlerMgr = pdfium::MakeUnique<CPDFSDK_AnnotHandlerMgr>(this);
    219   return m_pAnnotHandlerMgr.get();
    220 }
    221 
    222 CPDFSDK_ActionHandler* CPDFSDK_FormFillEnvironment::GetActionHander() {
    223   if (!m_pActionHandler)
    224     m_pActionHandler = pdfium::MakeUnique<CPDFSDK_ActionHandler>();
    225   return m_pActionHandler.get();
    226 }
    227 
    228 CFFL_InteractiveFormFiller*
    229 CPDFSDK_FormFillEnvironment::GetInteractiveFormFiller() {
    230   if (!m_pFormFiller)
    231     m_pFormFiller = pdfium::MakeUnique<CFFL_InteractiveFormFiller>(this);
    232   return m_pFormFiller.get();
    233 }
    234 
    235 void CPDFSDK_FormFillEnvironment::Invalidate(FPDF_PAGE page,
    236                                              const FX_RECT& rect) {
    237   if (m_pInfo && m_pInfo->FFI_Invalidate) {
    238     m_pInfo->FFI_Invalidate(m_pInfo, page, rect.left, rect.top, rect.right,
    239                             rect.bottom);
    240   }
    241 }
    242 
    243 void CPDFSDK_FormFillEnvironment::OutputSelectedRect(
    244     FPDF_PAGE page,
    245     const CFX_FloatRect& rect) {
    246   if (m_pInfo && m_pInfo->FFI_OutputSelectedRect) {
    247     m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, rect.left, rect.top,
    248                                     rect.right, rect.bottom);
    249   }
    250 }
    251 
    252 void CPDFSDK_FormFillEnvironment::SetCursor(int nCursorType) {
    253   if (m_pInfo && m_pInfo->FFI_SetCursor)
    254     m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
    255 }
    256 
    257 int CPDFSDK_FormFillEnvironment::SetTimer(int uElapse,
    258                                           TimerCallback lpTimerFunc) {
    259   if (m_pInfo && m_pInfo->FFI_SetTimer)
    260     return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
    261   return -1;
    262 }
    263 
    264 void CPDFSDK_FormFillEnvironment::KillTimer(int nTimerID) {
    265   if (m_pInfo && m_pInfo->FFI_KillTimer)
    266     m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
    267 }
    268 
    269 FX_SYSTEMTIME CPDFSDK_FormFillEnvironment::GetLocalTime() const {
    270   FX_SYSTEMTIME fxtime;
    271   if (!m_pInfo || !m_pInfo->FFI_GetLocalTime)
    272     return fxtime;
    273 
    274   FPDF_SYSTEMTIME systime = m_pInfo->FFI_GetLocalTime(m_pInfo);
    275   fxtime.wDay = systime.wDay;
    276   fxtime.wDayOfWeek = systime.wDayOfWeek;
    277   fxtime.wHour = systime.wHour;
    278   fxtime.wMilliseconds = systime.wMilliseconds;
    279   fxtime.wMinute = systime.wMinute;
    280   fxtime.wMonth = systime.wMonth;
    281   fxtime.wSecond = systime.wSecond;
    282   fxtime.wYear = systime.wYear;
    283   return fxtime;
    284 }
    285 
    286 void CPDFSDK_FormFillEnvironment::OnChange() {
    287   if (m_pInfo && m_pInfo->FFI_OnChange)
    288     m_pInfo->FFI_OnChange(m_pInfo);
    289 }
    290 
    291 bool CPDFSDK_FormFillEnvironment::IsSHIFTKeyDown(uint32_t nFlag) const {
    292   return (nFlag & FWL_EVENTFLAG_ShiftKey) != 0;
    293 }
    294 
    295 bool CPDFSDK_FormFillEnvironment::IsCTRLKeyDown(uint32_t nFlag) const {
    296   return (nFlag & FWL_EVENTFLAG_ControlKey) != 0;
    297 }
    298 
    299 bool CPDFSDK_FormFillEnvironment::IsALTKeyDown(uint32_t nFlag) const {
    300   return (nFlag & FWL_EVENTFLAG_AltKey) != 0;
    301 }
    302 
    303 FPDF_PAGE CPDFSDK_FormFillEnvironment::GetPage(FPDF_DOCUMENT document,
    304                                                int nPageIndex) {
    305   if (m_pInfo && m_pInfo->FFI_GetPage)
    306     return m_pInfo->FFI_GetPage(m_pInfo, document, nPageIndex);
    307   return nullptr;
    308 }
    309 
    310 FPDF_PAGE CPDFSDK_FormFillEnvironment::GetCurrentPage(FPDF_DOCUMENT document) {
    311   if (m_pInfo && m_pInfo->FFI_GetCurrentPage)
    312     return m_pInfo->FFI_GetCurrentPage(m_pInfo, document);
    313   return nullptr;
    314 }
    315 
    316 void CPDFSDK_FormFillEnvironment::ExecuteNamedAction(
    317     const FX_CHAR* namedAction) {
    318   if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
    319     m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
    320 }
    321 
    322 void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocus(
    323     FPDF_WIDESTRING focusText,
    324     FPDF_DWORD nTextLen,
    325     bool bFocus) {
    326   if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
    327     m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
    328 }
    329 
    330 void CPDFSDK_FormFillEnvironment::DoURIAction(const FX_CHAR* bsURI) {
    331   if (m_pInfo && m_pInfo->FFI_DoURIAction)
    332     m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
    333 }
    334 
    335 void CPDFSDK_FormFillEnvironment::DoGoToAction(int nPageIndex,
    336                                                int zoomMode,
    337                                                float* fPosArray,
    338                                                int sizeOfArray) {
    339   if (m_pInfo && m_pInfo->FFI_DoGoToAction) {
    340     m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray,
    341                               sizeOfArray);
    342   }
    343 }
    344 
    345 #ifdef PDF_ENABLE_XFA
    346 void CPDFSDK_FormFillEnvironment::DisplayCaret(FPDF_PAGE page,
    347                                                FPDF_BOOL bVisible,
    348                                                double left,
    349                                                double top,
    350                                                double right,
    351                                                double bottom) {
    352   if (m_pInfo && m_pInfo->FFI_DisplayCaret) {
    353     m_pInfo->FFI_DisplayCaret(m_pInfo, page, bVisible, left, top, right,
    354                               bottom);
    355   }
    356 }
    357 
    358 int CPDFSDK_FormFillEnvironment::GetCurrentPageIndex(FPDF_DOCUMENT document) {
    359   if (!m_pInfo || !m_pInfo->FFI_GetCurrentPageIndex)
    360     return -1;
    361   return m_pInfo->FFI_GetCurrentPageIndex(m_pInfo, document);
    362 }
    363 
    364 void CPDFSDK_FormFillEnvironment::SetCurrentPage(FPDF_DOCUMENT document,
    365                                                  int iCurPage) {
    366   if (m_pInfo && m_pInfo->FFI_SetCurrentPage)
    367     m_pInfo->FFI_SetCurrentPage(m_pInfo, document, iCurPage);
    368 }
    369 
    370 CFX_WideString CPDFSDK_FormFillEnvironment::GetPlatform() {
    371   if (!m_pInfo || !m_pInfo->FFI_GetPlatform)
    372     return L"";
    373 
    374   int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, nullptr, 0);
    375   if (nRequiredLen <= 0)
    376     return L"";
    377 
    378   char* pbuff = new char[nRequiredLen];
    379   memset(pbuff, 0, nRequiredLen);
    380   int nActualLen = m_pInfo->FFI_GetPlatform(m_pInfo, pbuff, nRequiredLen);
    381   if (nActualLen <= 0 || nActualLen > nRequiredLen) {
    382     delete[] pbuff;
    383     return L"";
    384   }
    385   CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
    386   CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
    387       (unsigned short*)bsRet.GetBuffer(bsRet.GetLength()),
    388       bsRet.GetLength() / sizeof(unsigned short));
    389   delete[] pbuff;
    390   return wsRet;
    391 }
    392 
    393 void CPDFSDK_FormFillEnvironment::GotoURL(FPDF_DOCUMENT document,
    394                                           const CFX_WideStringC& wsURL) {
    395   if (!m_pInfo || !m_pInfo->FFI_GotoURL)
    396     return;
    397 
    398   CFX_ByteString bsTo = CFX_WideString(wsURL).UTF16LE_Encode();
    399   FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(wsURL.GetLength());
    400   m_pInfo->FFI_GotoURL(m_pInfo, document, pTo);
    401   bsTo.ReleaseBuffer();
    402 }
    403 
    404 void CPDFSDK_FormFillEnvironment::GetPageViewRect(FPDF_PAGE page,
    405                                                   FS_RECTF& dstRect) {
    406   if (!m_pInfo || !m_pInfo->FFI_GetPageViewRect)
    407     return;
    408 
    409   double left;
    410   double top;
    411   double right;
    412   double bottom;
    413   m_pInfo->FFI_GetPageViewRect(m_pInfo, page, &left, &top, &right, &bottom);
    414 
    415   dstRect.left = static_cast<float>(left);
    416   dstRect.top = static_cast<float>(top < bottom ? bottom : top);
    417   dstRect.bottom = static_cast<float>(top < bottom ? top : bottom);
    418   dstRect.right = static_cast<float>(right);
    419 }
    420 
    421 bool CPDFSDK_FormFillEnvironment::PopupMenu(FPDF_PAGE page,
    422                                             FPDF_WIDGET hWidget,
    423                                             int menuFlag,
    424                                             CFX_PointF pt) {
    425   return m_pInfo && m_pInfo->FFI_PopupMenu &&
    426          m_pInfo->FFI_PopupMenu(m_pInfo, page, hWidget, menuFlag, pt.x, pt.y);
    427 }
    428 
    429 void CPDFSDK_FormFillEnvironment::Alert(FPDF_WIDESTRING Msg,
    430                                         FPDF_WIDESTRING Title,
    431                                         int Type,
    432                                         int Icon) {
    433   if (m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert) {
    434     m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, Msg, Title, Type,
    435                                       Icon);
    436   }
    437 }
    438 
    439 void CPDFSDK_FormFillEnvironment::EmailTo(FPDF_FILEHANDLER* fileHandler,
    440                                           FPDF_WIDESTRING pTo,
    441                                           FPDF_WIDESTRING pSubject,
    442                                           FPDF_WIDESTRING pCC,
    443                                           FPDF_WIDESTRING pBcc,
    444                                           FPDF_WIDESTRING pMsg) {
    445   if (m_pInfo && m_pInfo->FFI_EmailTo)
    446     m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg);
    447 }
    448 
    449 void CPDFSDK_FormFillEnvironment::UploadTo(FPDF_FILEHANDLER* fileHandler,
    450                                            int fileFlag,
    451                                            FPDF_WIDESTRING uploadTo) {
    452   if (m_pInfo && m_pInfo->FFI_UploadTo)
    453     m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
    454 }
    455 
    456 FPDF_FILEHANDLER* CPDFSDK_FormFillEnvironment::OpenFile(int fileType,
    457                                                         FPDF_WIDESTRING wsURL,
    458                                                         const char* mode) {
    459   if (m_pInfo && m_pInfo->FFI_OpenFile)
    460     return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
    461   return nullptr;
    462 }
    463 
    464 CFX_RetainPtr<IFX_SeekableReadStream>
    465 CPDFSDK_FormFillEnvironment::DownloadFromURL(const FX_WCHAR* url) {
    466   if (!m_pInfo || !m_pInfo->FFI_DownloadFromURL)
    467     return nullptr;
    468 
    469   CFX_ByteString bstrURL = CFX_WideString(url).UTF16LE_Encode();
    470   FPDF_WIDESTRING wsURL =
    471       (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength());
    472 
    473   FPDF_LPFILEHANDLER fileHandler = m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL);
    474   return MakeSeekableStream(fileHandler);
    475 }
    476 
    477 CFX_WideString CPDFSDK_FormFillEnvironment::PostRequestURL(
    478     const FX_WCHAR* wsURL,
    479     const FX_WCHAR* wsData,
    480     const FX_WCHAR* wsContentType,
    481     const FX_WCHAR* wsEncode,
    482     const FX_WCHAR* wsHeader) {
    483   if (!m_pInfo || !m_pInfo->FFI_PostRequestURL)
    484     return L"";
    485 
    486   CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
    487   FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
    488 
    489   CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
    490   FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
    491 
    492   CFX_ByteString bsContentType = CFX_WideString(wsContentType).UTF16LE_Encode();
    493   FPDF_WIDESTRING contentType =
    494       (FPDF_WIDESTRING)bsContentType.GetBuffer(bsContentType.GetLength());
    495 
    496   CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
    497   FPDF_WIDESTRING encode =
    498       (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
    499 
    500   CFX_ByteString bsHeader = CFX_WideString(wsHeader).UTF16LE_Encode();
    501   FPDF_WIDESTRING header =
    502       (FPDF_WIDESTRING)bsHeader.GetBuffer(bsHeader.GetLength());
    503 
    504   FPDF_BSTR response;
    505   FPDF_BStr_Init(&response);
    506   m_pInfo->FFI_PostRequestURL(m_pInfo, URL, data, contentType, encode, header,
    507                               &response);
    508 
    509   CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
    510       (FPDF_WIDESTRING)response.str, response.len / sizeof(FPDF_WIDESTRING));
    511   FPDF_BStr_Clear(&response);
    512 
    513   return wsRet;
    514 }
    515 
    516 FPDF_BOOL CPDFSDK_FormFillEnvironment::PutRequestURL(const FX_WCHAR* wsURL,
    517                                                      const FX_WCHAR* wsData,
    518                                                      const FX_WCHAR* wsEncode) {
    519   if (!m_pInfo || !m_pInfo->FFI_PutRequestURL)
    520     return false;
    521 
    522   CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
    523   FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
    524 
    525   CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
    526   FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
    527 
    528   CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
    529   FPDF_WIDESTRING encode =
    530       (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
    531 
    532   return m_pInfo->FFI_PutRequestURL(m_pInfo, URL, data, encode);
    533 }
    534 
    535 CFX_WideString CPDFSDK_FormFillEnvironment::GetLanguage() {
    536   if (!m_pInfo || !m_pInfo->FFI_GetLanguage)
    537     return L"";
    538 
    539   int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, nullptr, 0);
    540   if (nRequiredLen <= 0)
    541     return L"";
    542 
    543   char* pbuff = new char[nRequiredLen];
    544   memset(pbuff, 0, nRequiredLen);
    545   int nActualLen = m_pInfo->FFI_GetLanguage(m_pInfo, pbuff, nRequiredLen);
    546   if (nActualLen <= 0 || nActualLen > nRequiredLen) {
    547     delete[] pbuff;
    548     return L"";
    549   }
    550   CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
    551   CFX_WideString wsRet = CFX_WideString::FromUTF16LE(
    552       (FPDF_WIDESTRING)bsRet.GetBuffer(bsRet.GetLength()),
    553       bsRet.GetLength() / sizeof(FPDF_WIDESTRING));
    554   delete[] pbuff;
    555   return wsRet;
    556 }
    557 
    558 void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount,
    559                                             uint32_t dwEventType) const {
    560   if (m_pInfo && m_pInfo->FFI_PageEvent)
    561     m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType);
    562 }
    563 #endif  // PDF_ENABLE_XFA
    564 
    565 void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() {
    566   for (auto& it : m_PageMap) {
    567     if (it.second->IsValidSDKAnnot(GetFocusAnnot()))
    568       KillFocusAnnot(0);
    569   }
    570 }
    571 
    572 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(
    573     UnderlyingPageType* pUnderlyingPage,
    574     bool renew) {
    575   auto it = m_PageMap.find(pUnderlyingPage);
    576   if (it != m_PageMap.end())
    577     return it->second.get();
    578 
    579   if (!renew)
    580     return nullptr;
    581 
    582   CPDFSDK_PageView* pPageView = new CPDFSDK_PageView(this, pUnderlyingPage);
    583   m_PageMap[pUnderlyingPage].reset(pPageView);
    584   // Delay to load all the annotations, to avoid endless loop.
    585   pPageView->LoadFXAnnots();
    586   return pPageView;
    587 }
    588 
    589 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() {
    590   UnderlyingPageType* pPage =
    591       UnderlyingFromFPDFPage(GetCurrentPage(m_pUnderlyingDoc));
    592   return pPage ? GetPageView(pPage, true) : nullptr;
    593 }
    594 
    595 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) {
    596   UnderlyingPageType* pTempPage =
    597       UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
    598   if (!pTempPage)
    599     return nullptr;
    600 
    601   auto it = m_PageMap.find(pTempPage);
    602   return it != m_PageMap.end() ? it->second.get() : nullptr;
    603 }
    604 
    605 void CPDFSDK_FormFillEnvironment::ProcJavascriptFun() {
    606   CPDF_Document* pPDFDoc = GetPDFDocument();
    607   CPDF_DocJSActions docJS(pPDFDoc);
    608   int iCount = docJS.CountJSActions();
    609   if (iCount < 1)
    610     return;
    611   for (int i = 0; i < iCount; i++) {
    612     CFX_ByteString csJSName;
    613     CPDF_Action jsAction = docJS.GetJSAction(i, csJSName);
    614     if (GetActionHander()) {
    615       GetActionHander()->DoAction_JavaScript(
    616           jsAction, CFX_WideString::FromLocal(csJSName.AsStringC()), this);
    617     }
    618   }
    619 }
    620 
    621 bool CPDFSDK_FormFillEnvironment::ProcOpenAction() {
    622   if (!m_pUnderlyingDoc)
    623     return false;
    624 
    625   CPDF_Dictionary* pRoot = GetPDFDocument()->GetRoot();
    626   if (!pRoot)
    627     return false;
    628 
    629   CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction");
    630   if (!pOpenAction)
    631     pOpenAction = pRoot->GetArrayFor("OpenAction");
    632 
    633   if (!pOpenAction)
    634     return false;
    635 
    636   if (pOpenAction->IsArray())
    637     return true;
    638 
    639   if (CPDF_Dictionary* pDict = pOpenAction->AsDictionary()) {
    640     CPDF_Action action(pDict);
    641     if (GetActionHander())
    642       GetActionHander()->DoAction_DocOpen(action, this);
    643     return true;
    644   }
    645   return false;
    646 }
    647 
    648 void CPDFSDK_FormFillEnvironment::RemovePageView(
    649     UnderlyingPageType* pUnderlyingPage) {
    650   auto it = m_PageMap.find(pUnderlyingPage);
    651   if (it == m_PageMap.end())
    652     return;
    653 
    654   CPDFSDK_PageView* pPageView = it->second.get();
    655   if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
    656     return;
    657 
    658   // Mark the page view so we do not come into |RemovePageView| a second
    659   // time while we're in the process of removing.
    660   pPageView->SetBeingDestroyed();
    661 
    662   // This must happen before we remove |pPageView| from the map because
    663   // |KillFocusAnnot| can call into the |GetPage| method which will
    664   // look for this page view in the map, if it doesn't find it a new one will
    665   // be created. We then have two page views pointing to the same page and
    666   // bad things happen.
    667   if (pPageView->IsValidSDKAnnot(GetFocusAnnot()))
    668     KillFocusAnnot(0);
    669 
    670   // Remove the page from the map to make sure we don't accidentally attempt
    671   // to use the |pPageView| while we're cleaning it up.
    672   m_PageMap.erase(it);
    673 }
    674 
    675 UnderlyingPageType* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) {
    676   return UnderlyingFromFPDFPage(GetPage(m_pUnderlyingDoc, nIndex));
    677 }
    678 
    679 CPDFSDK_InterForm* CPDFSDK_FormFillEnvironment::GetInterForm() {
    680   if (!m_pInterForm)
    681     m_pInterForm = pdfium::MakeUnique<CPDFSDK_InterForm>(this);
    682   return m_pInterForm.get();
    683 }
    684 
    685 void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender,
    686                                                  CPDFSDK_Annot* pAnnot) {
    687   for (const auto& it : m_PageMap) {
    688     CPDFSDK_PageView* pPageView = it.second.get();
    689     if (pPageView != pSender)
    690       pPageView->UpdateView(pAnnot);
    691   }
    692 }
    693 
    694 bool CPDFSDK_FormFillEnvironment::SetFocusAnnot(
    695     CPDFSDK_Annot::ObservedPtr* pAnnot) {
    696   if (m_bBeingDestroyed)
    697     return false;
    698   if (m_pFocusAnnot == *pAnnot)
    699     return true;
    700   if (m_pFocusAnnot && !KillFocusAnnot(0))
    701     return false;
    702   if (!*pAnnot)
    703     return false;
    704 
    705 #ifdef PDF_ENABLE_XFA
    706   CPDFSDK_Annot::ObservedPtr pLastFocusAnnot(m_pFocusAnnot.Get());
    707 #endif  // PDF_ENABLE_XFA
    708   CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
    709   if (pPageView && pPageView->IsValid()) {
    710     CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
    711     if (!m_pFocusAnnot) {
    712 #ifdef PDF_ENABLE_XFA
    713       if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot))
    714         return false;
    715 #endif  // PDF_ENABLE_XFA
    716       if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0))
    717         return false;
    718       if (!m_pFocusAnnot) {
    719         m_pFocusAnnot.Reset(pAnnot->Get());
    720         return true;
    721       }
    722     }
    723   }
    724   return false;
    725 }
    726 
    727 bool CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) {
    728   if (m_pFocusAnnot) {
    729     CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
    730     CPDFSDK_Annot::ObservedPtr pFocusAnnot(m_pFocusAnnot.Get());
    731     m_pFocusAnnot.Reset();
    732 
    733 #ifdef PDF_ENABLE_XFA
    734     CPDFSDK_Annot::ObservedPtr pNull;
    735     if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot))
    736       return false;
    737 #endif  // PDF_ENABLE_XFA
    738 
    739     if (pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) {
    740       if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
    741         CPDFSDK_Widget* pWidget =
    742             static_cast<CPDFSDK_Widget*>(pFocusAnnot.Get());
    743         int nFieldType = pWidget->GetFieldType();
    744         if (FIELDTYPE_TEXTFIELD == nFieldType ||
    745             FIELDTYPE_COMBOBOX == nFieldType) {
    746           OnSetFieldInputFocus(nullptr, 0, false);
    747         }
    748       }
    749       if (!m_pFocusAnnot)
    750         return true;
    751     } else {
    752       m_pFocusAnnot.Reset(pFocusAnnot.Get());
    753     }
    754   }
    755   return false;
    756 }
    757 
    758 bool CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) {
    759   return !!(GetPDFDocument()->GetUserPermissions() & nFlag);
    760 }
    761