Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DownloadHandler does not work with JS opened popup window #175

Open
magreenblatt opened this issue Jul 14, 2015 · 6 comments
Open

DownloadHandler does not work with JS opened popup window #175

magreenblatt opened this issue Jul 14, 2015 · 6 comments
Labels
bug Bug report

Comments

@magreenblatt
Copy link
Collaborator

Original report by Dominic E. (Bitbucket: Dominic E.).


What steps will reproduce the problem?

  • create a jcef project. implement some handler, e.g. downloadhandler
  • run project
  • create/open with javascript a new window -> open("http://google.com");
  • navigate with javascript window to a page where you can dl sth

What is the expected output? What do you see instead?

  • dl doesn't start
  • No harm done

What version of the product are you using? On what operating system?

  • jcef 2171 (MacOsX) and 2357 (Windows)

Does the problem reproduce with the JCEF simple or detailed sample application at the same version?

  • yes

How about with a newer or older version?

  • only tried 2171 and 2357

Does the problem reproduce with the cefclient or cefsimple application at the same version?

  • no, in cpp it will be handled but not passed to java

Some more information: MagPCSS

@magreenblatt
Copy link
Collaborator Author

Original comment by Dominic E. (Bitbucket: Dominic E.).


The problem exists in latest jcef (2454), too.
Plus the problems, that javascript-windows will open in background and if you will put them to foreground it's possible, that the application will crash.

@magreenblatt
Copy link
Collaborator Author

Original comment by Dominic E. (Bitbucket: Dominic E.).


@magreenblatt
Any news/information about this?
On latest jcef (25xx) still no handler is working with JS opened windows (window.open(...))

All requests will be handled in cpp but none of them will be passed to java

@magreenblatt
Copy link
Collaborator Author

Are the DownloadHandler methods in download_handler.cpp called when you start the download from the popup window? That would be a good place to start for debugging the problem.

@magreenblatt
Copy link
Collaborator Author

Original comment by Dominic E. (Bitbucket: Dominic E.).


This is how I handle downloads at the moment:

#!c++

// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "download_handler.h"
#include "client_handler.h"

#include "jni_util.h"
#include "util.h"

#if defined(OS_MACOSX)
    #include "util_mac.h"
#elif defined(OS_WIN)
    #include <Windows.h>
    #include <shlobj.h>
#endif

DownloadHandler::DownloadHandler(JNIEnv* env, jobject handler) {
  jhandler_ = env->NewGlobalRef(handler);
}

DownloadHandler::~DownloadHandler() {
  JNIEnv* env = GetJNIEnv();
  env->DeleteGlobalRef(jhandler_);
}

void DownloadHandler::OnBeforeDownload(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefDownloadItem> download_item,
    const CefString& suggested_name,
    CefRefPtr<CefBeforeDownloadCallback> callback) {
  JNIEnv* env = GetJNIEnv();
  if (!env)
    return;

    if (browser->IsPopup()) //Javascript window
    {
        // start download from here, because it won't be passed to Java
        
        std::string path;
        
#if defined(OS_MACOSX)
        
        path = util_mac::GetDownloadPath();
        path += "/" + suggested_name.ToString();
        callback->Continue(path, false);
        
#elif defined(OS_WIN)
        
        TCHAR szFolderPath[MAX_PATH];
        if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szFolderPath)))
        {
            path = CefString(szFolderPath);
            path += "\\xyz\\" + suggested_name.ToString();
            callback->Continue(path, false);
        }
        
#endif
        
        return;
    }
    
  jobject jdownloadItem = NewJNIObject(env, "org/cef/callback/CefDownloadItem_N");
  if (!jdownloadItem)
    return;
  SetCefForJNIObject(env, jdownloadItem, download_item.get(), "CefDownloadItem");

  jobject jcallback  = NewJNIObject(env, "org/cef/callback/CefBeforeDownloadCallback_N");
  if (!jcallback)
    return;
  SetCefForJNIObject(env, jcallback, callback.get(), "CefBeforeDownloadCallback");

  JNI_CALL_VOID_METHOD(env, jhandler_, 
                       "onBeforeDownload", 
                       "(Lorg/cef/browser/CefBrowser;Lorg/cef/callback/CefDownloadItem;"
                       "Ljava/lang/String;Lorg/cef/callback/CefBeforeDownloadCallback;)V",
                       GetJNIBrowser(browser),
                       jdownloadItem,
                       NewJNIString(env, suggested_name),
                       jcallback);

  // delete CefDownloadItem reference from Java because the object
  // is only valid within this call
  SetCefForJNIObject<CefDownloadItem>(env, jdownloadItem,
                                      NULL, "CefDownloadItem");
}

void DownloadHandler::OnDownloadUpdated(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefDownloadItem> download_item,
      CefRefPtr<CefDownloadItemCallback> callback) {
  JNIEnv* env = GetJNIEnv();
  if (!env)
    return;

    if (browser->IsPopup())
    {
        if (download_item->IsComplete())
        {
            browser->GetFocusedFrame()->ExecuteJavaScript("self.close();", browser->GetFocusedFrame()->GetURL(), 0);
            
            std::stringstream cmd;
            
#if defined(OS_MACOSX)
            cmd << "open -n -R " << download_item->GetFullPath().ToString();
#elif defined(OS_WIN)
            cmd << "explorer.exe /select,\"" << download_item->GetFullPath().ToString() << "\"";
#endif
            
            system(cmd.str().c_str());
        }
        return;
    }
    
  jobject jdownloadItem = NewJNIObject(env, "org/cef/callback/CefDownloadItem_N");
  if (!jdownloadItem)
    return;
  SetCefForJNIObject(env, jdownloadItem, download_item.get(), "CefDownloadItem");

  jobject jcallback  = NewJNIObject(env, "org/cef/callback/CefDownloadItemCallback_N");
  if (!jcallback)
    return;
  SetCefForJNIObject(env, jcallback, callback.get(), "CefDownloadItemCallback");

  JNI_CALL_VOID_METHOD(env, jhandler_,
                       "onDownloadUpdated",
                       "(Lorg/cef/browser/CefBrowser;Lorg/cef/callback/CefDownloadItem;"
                       "Lorg/cef/callback/CefDownloadItemCallback;)V",
                       GetJNIBrowser(browser),
                       jdownloadItem,
                       jcallback);

  // delete CefDownloadItem reference from Java because the object
  // is only valid within this call
  SetCefForJNIObject<CefDownloadItem>(env, jdownloadItem,
                                      NULL, "CefDownloadItem");
}

Either here

SetCefForJNIObject(env, jdownloadItem, download_item.get(), "CefDownloadItem");

or here

SetCefForJNIObject(env, jcallback, callback.get(), "CefBeforeDownloadCallback");

it crashes (I don't know anymore)

@magreenblatt
Copy link
Collaborator Author

Original comment by János Gerevich (Bitbucket: JohnTheHun, GitHub: JohnTheHun).


The Downloadhandler still doesn’t carry over in jcef version 3.3538.199.gd64cd6c

I have also created a forum topic here about this but received no useful reply: https://magpcss.org/ceforum/viewtopic.php?f=17&t=16560

Is there any solution to this? Or do I have to create a custom mechanism to handle creation of popups to use my Downloadhandler in popups?

Thank you!

@magreenblatt
Copy link
Collaborator Author

  • changed title from "No control over a in JS opened window" to "DownloadHandler does not work with JS opened popup window"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug report
Projects
None yet
Development

No branches or pull requests

1 participant