609 lines
21 KiB
C++
609 lines
21 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2017 - ROLI Ltd.
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
|
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
|
27th April 2017).
|
|
|
|
End User License Agreement: www.juce.com/juce-5-licence
|
|
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
namespace juce
|
|
{
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (constructor, "<init>", "(Landroid/content/Context;)V") \
|
|
METHOD (getSettings, "getSettings", "()Landroid/webkit/WebSettings;") \
|
|
METHOD (goBack, "goBack", "()V") \
|
|
METHOD (goForward, "goForward", "()V") \
|
|
METHOD (loadDataWithBaseURL, "loadDataWithBaseURL", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") \
|
|
METHOD (loadUrl, "loadUrl", "(Ljava/lang/String;Ljava/util/Map;)V") \
|
|
METHOD (postUrl, "postUrl", "(Ljava/lang/String;[B)V") \
|
|
METHOD (reload, "reload", "()V") \
|
|
METHOD (setWebChromeClient, "setWebChromeClient", "(Landroid/webkit/WebChromeClient;)V") \
|
|
METHOD (setWebViewClient, "setWebViewClient", "(Landroid/webkit/WebViewClient;)V") \
|
|
METHOD (stopLoading, "stopLoading", "()V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidWebView, "android/webkit/WebView")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (constructor, "<init>", "()V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidWebChromeClient, "android/webkit/WebChromeClient");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (constructor, "<init>", "()V")
|
|
|
|
DECLARE_JNI_CLASS (AndroidWebViewClient, "android/webkit/WebViewClient");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
STATICMETHOD (getInstance, "getInstance", "()Landroid/webkit/CookieManager;")
|
|
|
|
DECLARE_JNI_CLASS (AndroidCookieManager, "android/webkit/CookieManager");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (constructor, "<init>", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH ";J)V")
|
|
|
|
DECLARE_JNI_CLASS (JuceWebChromeClient, JUCE_ANDROID_ACTIVITY_CLASSPATH "$JuceWebChromeClient");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (constructor, "<init>", "(L" JUCE_ANDROID_ACTIVITY_CLASSPATH ";J)V") \
|
|
METHOD (hostDeleted, "hostDeleted", "()V")
|
|
|
|
DECLARE_JNI_CLASS (JuceWebViewClient, JUCE_ANDROID_ACTIVITY_CLASSPATH "$JuceWebViewClient");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (setBuiltInZoomControls, "setBuiltInZoomControls", "(Z)V") \
|
|
METHOD (setDisplayZoomControls, "setDisplayZoomControls", "(Z)V") \
|
|
METHOD (setJavaScriptEnabled, "setJavaScriptEnabled", "(Z)V") \
|
|
METHOD (setSupportMultipleWindows, "setSupportMultipleWindows", "(Z)V")
|
|
|
|
DECLARE_JNI_CLASS (WebSettings, "android/webkit/WebSettings");
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
METHOD (toString, "toString", "()Ljava/lang/String;")
|
|
|
|
DECLARE_JNI_CLASS (SslError, "android/net/http/SslError")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
|
|
STATICMETHOD (encode, "encode", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;")
|
|
|
|
DECLARE_JNI_CLASS (URLEncoder, "java/net/URLEncoder")
|
|
#undef JNI_CLASS_MEMBERS
|
|
|
|
//==============================================================================
|
|
class WebBrowserComponent::Pimpl : public AndroidViewComponent,
|
|
public AsyncUpdater
|
|
{
|
|
public:
|
|
Pimpl (WebBrowserComponent& o)
|
|
: AndroidViewComponent (true),
|
|
owner (o)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
setView (env->NewObject (AndroidWebView, AndroidWebView.constructor, android.activity.get()));
|
|
|
|
auto settings = LocalRef<jobject> (env->CallObjectMethod ((jobject) getView(), AndroidWebView.getSettings));
|
|
env->CallVoidMethod (settings, WebSettings.setJavaScriptEnabled, true);
|
|
env->CallVoidMethod (settings, WebSettings.setBuiltInZoomControls, true);
|
|
env->CallVoidMethod (settings, WebSettings.setDisplayZoomControls, false);
|
|
env->CallVoidMethod (settings, WebSettings.setSupportMultipleWindows, true);
|
|
|
|
juceWebChromeClient = GlobalRef (LocalRef<jobject> (env->NewObject (JuceWebChromeClient, JuceWebChromeClient.constructor,
|
|
android.activity.get(),
|
|
reinterpret_cast<jlong>(&owner))));
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.setWebChromeClient, juceWebChromeClient.get());
|
|
|
|
juceWebViewClient = GlobalRef (LocalRef<jobject> (env->NewObject (JuceWebViewClient, JuceWebViewClient.constructor,
|
|
android.activity.get(),
|
|
reinterpret_cast<jlong>(&owner))));
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.setWebViewClient, juceWebViewClient.get());
|
|
}
|
|
|
|
~Pimpl()
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.stopLoading);
|
|
|
|
auto defaultChromeClient = LocalRef<jobject> (env->NewObject (AndroidWebChromeClient, AndroidWebChromeClient.constructor));
|
|
auto defaultViewClient = LocalRef<jobject> (env->NewObject (AndroidWebViewClient, AndroidWebViewClient .constructor));
|
|
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.setWebChromeClient, defaultChromeClient.get());
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.setWebViewClient, defaultViewClient .get());
|
|
|
|
masterReference.clear();
|
|
|
|
// if other Java thread is waiting for us to respond to page load request
|
|
// wake it up immediately (false answer will be sent), so that it releases
|
|
// the lock we need when calling hostDeleted.
|
|
responseReadyEvent.signal();
|
|
|
|
env->CallVoidMethod (juceWebViewClient, JuceWebViewClient.hostDeleted);
|
|
}
|
|
|
|
void goToURL (const String& url,
|
|
const StringArray* headers,
|
|
const MemoryBlock* postData)
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
if (headers == nullptr && postData == nullptr)
|
|
{
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.loadUrl, javaString (url).get(), 0);
|
|
}
|
|
else if (headers != nullptr && postData == nullptr)
|
|
{
|
|
auto headersMap = LocalRef<jobject> (env->NewObject (JavaHashMap,
|
|
JavaHashMap.constructorWithCapacity,
|
|
headers->size()));
|
|
|
|
for (const auto& header : *headers)
|
|
{
|
|
auto name = header.upToFirstOccurrenceOf (":", false, false).trim();
|
|
auto value = header.fromFirstOccurrenceOf (":", false, false).trim();
|
|
|
|
env->CallObjectMethod (headersMap, JavaMap.put,
|
|
javaString (name).get(),
|
|
javaString (value).get());
|
|
}
|
|
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.loadUrl,
|
|
javaString (url).get(), headersMap.get());
|
|
}
|
|
else if (headers == nullptr && postData != nullptr)
|
|
{
|
|
auto dataStringJuce = postData->toString();
|
|
auto dataStringJava = javaString (dataStringJuce);
|
|
auto encodingString = LocalRef<jobject> (env->CallStaticObjectMethod (URLEncoder, URLEncoder.encode,
|
|
dataStringJava.get(), javaString ("utf-8").get()));
|
|
|
|
auto bytes = LocalRef<jbyteArray> ((jbyteArray) env->CallObjectMethod (encodingString, JavaString.getBytes));
|
|
|
|
env->CallVoidMethod ((jobject) getView(), AndroidWebView.postUrl,
|
|
javaString (url).get(), bytes.get());
|
|
}
|
|
else if (headers != nullptr && postData != nullptr)
|
|
{
|
|
// There is no support for both extra headers and post data in Android WebView, so
|
|
// we need to open URL manually.
|
|
|
|
URL urlToUse = URL (url).withPOSTData (*postData);
|
|
connectionThread.reset (new ConnectionThread (*this, urlToUse, *headers));
|
|
}
|
|
}
|
|
|
|
void stop()
|
|
{
|
|
connectionThread = nullptr;
|
|
|
|
getEnv()->CallVoidMethod ((jobject) getView(), AndroidWebView.stopLoading);
|
|
}
|
|
|
|
void goBack()
|
|
{
|
|
connectionThread = nullptr;
|
|
|
|
getEnv()->CallVoidMethod ((jobject) getView(), AndroidWebView.goBack);
|
|
}
|
|
|
|
void goForward()
|
|
{
|
|
connectionThread = nullptr;
|
|
|
|
getEnv()->CallVoidMethod ((jobject) getView(), AndroidWebView.goForward);
|
|
}
|
|
|
|
void refresh()
|
|
{
|
|
connectionThread = nullptr;
|
|
|
|
getEnv()->CallVoidMethod ((jobject) getView(), AndroidWebView.reload);
|
|
}
|
|
|
|
void handleAsyncUpdate()
|
|
{
|
|
jassert (connectionThread != nullptr);
|
|
|
|
if (connectionThread == nullptr)
|
|
return;
|
|
|
|
auto& result = connectionThread->getResult();
|
|
|
|
if (result.statusCode >= 200 && result.statusCode < 300)
|
|
{
|
|
auto url = javaString (result.url);
|
|
auto data = javaString (result.data);
|
|
auto mimeType = javaString ("text/html");
|
|
auto encoding = javaString ("utf-8");
|
|
|
|
getEnv()->CallVoidMethod ((jobject) getView(), AndroidWebView.loadDataWithBaseURL,
|
|
url.get(), data.get(), mimeType.get(),
|
|
encoding.get(), 0);
|
|
}
|
|
else
|
|
{
|
|
owner.pageLoadHadNetworkError (result.description);
|
|
}
|
|
}
|
|
|
|
bool handlePageAboutToLoad (const String& url)
|
|
{
|
|
if (MessageManager::getInstance()->isThisTheMessageThread())
|
|
return owner.pageAboutToLoad (url);
|
|
|
|
WeakReference<Pimpl> weakRef (this);
|
|
|
|
if (weakRef == nullptr)
|
|
return false;
|
|
|
|
responseReadyEvent.reset();
|
|
|
|
bool shouldLoad = false;
|
|
|
|
MessageManager::callAsync ([weakRef, url, &shouldLoad]
|
|
{
|
|
if (weakRef == nullptr)
|
|
return;
|
|
|
|
shouldLoad = weakRef->owner.pageAboutToLoad (url);
|
|
|
|
weakRef->responseReadyEvent.signal();
|
|
});
|
|
|
|
responseReadyEvent.wait (-1);
|
|
|
|
return shouldLoad;
|
|
}
|
|
|
|
private:
|
|
class ConnectionThread : private Thread
|
|
{
|
|
public:
|
|
struct Result
|
|
{
|
|
String url;
|
|
int statusCode = 0;
|
|
String description;
|
|
String data;
|
|
};
|
|
|
|
ConnectionThread (Pimpl& ownerToUse,
|
|
URL& url,
|
|
const StringArray& headers)
|
|
: Thread ("WebBrowserComponent::Pimpl::ConnectionThread"),
|
|
owner (ownerToUse),
|
|
webInputStream (new WebInputStream (url, true))
|
|
{
|
|
webInputStream->withExtraHeaders (headers.joinIntoString ("\n"));
|
|
webInputStream->withConnectionTimeout (10000);
|
|
|
|
result.url = url.toString (true);
|
|
|
|
startThread();
|
|
}
|
|
|
|
~ConnectionThread()
|
|
{
|
|
webInputStream->cancel();
|
|
signalThreadShouldExit();
|
|
waitForThreadToExit (10000);
|
|
|
|
webInputStream = nullptr;
|
|
}
|
|
|
|
void run() override
|
|
{
|
|
if (! webInputStream->connect (nullptr))
|
|
{
|
|
result.description = "Could not establish connection";
|
|
owner.triggerAsyncUpdate();
|
|
return;
|
|
}
|
|
|
|
result.statusCode = webInputStream->getStatusCode();
|
|
result.description = "Status code: " + String (result.statusCode);
|
|
readFromInputStream();
|
|
owner.triggerAsyncUpdate();
|
|
}
|
|
|
|
const Result& getResult() { return result; }
|
|
|
|
private:
|
|
void readFromInputStream()
|
|
{
|
|
MemoryOutputStream ostream;
|
|
|
|
while (true)
|
|
{
|
|
if (threadShouldExit())
|
|
return;
|
|
|
|
char buffer [8192];
|
|
const int num = webInputStream->read (buffer, sizeof (buffer));
|
|
|
|
if (num <= 0)
|
|
break;
|
|
|
|
ostream.write (buffer, (size_t) num);
|
|
}
|
|
|
|
result.data = ostream.toUTF8();
|
|
}
|
|
|
|
Pimpl& owner;
|
|
std::unique_ptr<WebInputStream> webInputStream;
|
|
Result result;
|
|
};
|
|
|
|
|
|
WebBrowserComponent& owner;
|
|
GlobalRef juceWebChromeClient;
|
|
GlobalRef juceWebViewClient;
|
|
std::unique_ptr<ConnectionThread> connectionThread;
|
|
WaitableEvent responseReadyEvent;
|
|
|
|
WeakReference<Pimpl>::Master masterReference;
|
|
friend class WeakReference<Pimpl>;
|
|
};
|
|
|
|
//==============================================================================
|
|
WebBrowserComponent::WebBrowserComponent (const bool unloadWhenHidden)
|
|
: blankPageShown (false),
|
|
unloadPageWhenBrowserIsHidden (unloadWhenHidden)
|
|
{
|
|
setOpaque (true);
|
|
|
|
browser.reset (new Pimpl (*this));
|
|
addAndMakeVisible (browser.get());
|
|
}
|
|
|
|
WebBrowserComponent::~WebBrowserComponent()
|
|
{
|
|
}
|
|
|
|
//==============================================================================
|
|
void WebBrowserComponent::goToURL (const String& url,
|
|
const StringArray* headers,
|
|
const MemoryBlock* postData)
|
|
{
|
|
lastURL = url;
|
|
|
|
if (headers != nullptr)
|
|
lastHeaders = *headers;
|
|
else
|
|
lastHeaders.clear();
|
|
|
|
if (postData != nullptr)
|
|
lastPostData = *postData;
|
|
else
|
|
lastPostData.reset();
|
|
|
|
blankPageShown = false;
|
|
|
|
browser->goToURL (url, headers, postData);
|
|
}
|
|
|
|
void WebBrowserComponent::stop()
|
|
{
|
|
browser->stop();
|
|
}
|
|
|
|
void WebBrowserComponent::goBack()
|
|
{
|
|
lastURL.clear();
|
|
blankPageShown = false;
|
|
|
|
browser->goBack();
|
|
}
|
|
|
|
void WebBrowserComponent::goForward()
|
|
{
|
|
lastURL.clear();
|
|
|
|
browser->goForward();
|
|
}
|
|
|
|
void WebBrowserComponent::refresh()
|
|
{
|
|
browser->refresh();
|
|
}
|
|
|
|
//==============================================================================
|
|
void WebBrowserComponent::paint (Graphics& g)
|
|
{
|
|
g.fillAll (Colours::white);
|
|
}
|
|
|
|
void WebBrowserComponent::checkWindowAssociation()
|
|
{
|
|
if (isShowing())
|
|
{
|
|
if (blankPageShown)
|
|
goBack();
|
|
}
|
|
else
|
|
{
|
|
if (unloadPageWhenBrowserIsHidden && ! blankPageShown)
|
|
{
|
|
// when the component becomes invisible, some stuff like flash
|
|
// carries on playing audio, so we need to force it onto a blank
|
|
// page to avoid this, (and send it back when it's made visible again).
|
|
|
|
blankPageShown = true;
|
|
browser->goToURL ("about:blank", 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WebBrowserComponent::reloadLastURL()
|
|
{
|
|
if (lastURL.isNotEmpty())
|
|
{
|
|
goToURL (lastURL, &lastHeaders, lastPostData.getSize() == 0 ? nullptr : &lastPostData);
|
|
lastURL.clear();
|
|
}
|
|
}
|
|
|
|
void WebBrowserComponent::parentHierarchyChanged()
|
|
{
|
|
checkWindowAssociation();
|
|
}
|
|
|
|
void WebBrowserComponent::resized()
|
|
{
|
|
browser->setSize (getWidth(), getHeight());
|
|
}
|
|
|
|
void WebBrowserComponent::visibilityChanged()
|
|
{
|
|
checkWindowAssociation();
|
|
}
|
|
|
|
void WebBrowserComponent::focusGained (FocusChangeType)
|
|
{
|
|
}
|
|
|
|
void WebBrowserComponent::clearCookies()
|
|
{
|
|
auto* env = getEnv();
|
|
|
|
auto cookieManager = LocalRef<jobject> (env->CallStaticObjectMethod (AndroidCookieManager,
|
|
AndroidCookieManager.getInstance));
|
|
|
|
const bool apiAtLeast21 = env->CallStaticIntMethod (JuceAppActivity, JuceAppActivity.getAndroidSDKVersion) >= 21;
|
|
|
|
jmethodID clearCookiesMethod = 0;
|
|
|
|
if (apiAtLeast21)
|
|
{
|
|
clearCookiesMethod = env->GetMethodID (AndroidCookieManager, "removeAllCookies", "(Landroid/webkit/ValueCallback;)V");
|
|
env->CallVoidMethod (cookieManager, clearCookiesMethod, 0);
|
|
}
|
|
else
|
|
{
|
|
clearCookiesMethod = env->GetMethodID (AndroidCookieManager, "removeAllCookie", "()V");
|
|
env->CallVoidMethod (cookieManager, clearCookiesMethod);
|
|
}
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewPageLoadStarted, bool, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/, jobject url))
|
|
{
|
|
setEnv (env);
|
|
|
|
return juce_webViewPageLoadStarted (reinterpret_cast<WebBrowserComponent*> (host),
|
|
juceString (static_cast<jstring> (url)));
|
|
}
|
|
|
|
bool juce_webViewPageLoadStarted (WebBrowserComponent* browserComponent, const String& url)
|
|
{
|
|
return browserComponent->browser->handlePageAboutToLoad (url);
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewPageLoadFinished, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/, jobject url))
|
|
{
|
|
setEnv (env);
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageFinishedLoading (juceString (static_cast<jstring> (url)));
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewReceivedError, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/, jobject /*request*/, jobject error))
|
|
{
|
|
setEnv (env);
|
|
|
|
jclass errorClass = env->FindClass ("android/webkit/WebResourceError");
|
|
|
|
if (errorClass != 0)
|
|
{
|
|
jmethodID method = env->GetMethodID (errorClass, "getDescription", "()Ljava/lang/CharSequence;");
|
|
|
|
if (method != 0)
|
|
{
|
|
auto sequence = LocalRef<jobject> (env->CallObjectMethod (error, method));
|
|
auto errorString = LocalRef<jstring> ((jstring) env->CallObjectMethod (sequence, JavaCharSequence.toString));
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageLoadHadNetworkError (juceString (errorString));
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Should never get here!
|
|
jassertfalse;
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageLoadHadNetworkError ({});
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewReceivedHttpError, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/, jobject /*request*/, jobject errorResponse))
|
|
{
|
|
setEnv (env);
|
|
|
|
jclass responseClass = env->FindClass ("android/webkit/WebResourceResponse");
|
|
|
|
if (responseClass != 0)
|
|
{
|
|
jmethodID method = env->GetMethodID (responseClass, "getReasonPhrase", "()Ljava/lang/String;");
|
|
|
|
if (method != 0)
|
|
{
|
|
auto errorString = LocalRef<jstring> ((jstring) env->CallObjectMethod (errorResponse, method));
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageLoadHadNetworkError (juceString (errorString));
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Should never get here!
|
|
jassertfalse;
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageLoadHadNetworkError ({});
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewReceivedSslError, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/, jobject /*sslErrorHandler*/, jobject sslError))
|
|
{
|
|
setEnv (env);
|
|
|
|
auto errorString = LocalRef<jstring> ((jstring) env->CallObjectMethod (sslError, SslError.toString));
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->pageLoadHadNetworkError (juceString (errorString));
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewCloseWindowRequest, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/))
|
|
{
|
|
setEnv (env);
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->windowCloseRequest();
|
|
}
|
|
|
|
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, webViewCreateWindowRequest, void, (JNIEnv* env, jobject /*activity*/, jlong host, jobject /*webView*/))
|
|
{
|
|
setEnv (env);
|
|
|
|
reinterpret_cast<WebBrowserComponent*> (host)->newWindowAttemptingToLoad ({});
|
|
}
|
|
|
|
|
|
} // namespace juce
|