iosWebViewFix/flutter_inappwebview_windows/windows/webview_environment/webview_environment_manager...

129 lines
4.9 KiB
C++

#include <DispatcherQueue.h>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include "../in_app_webview/in_app_webview_settings.h"
#include "../utils/flutter.h"
#include "../utils/log.h"
#include "../utils/string.h"
#include "../utils/vector.h"
#include "webview_environment_manager.h"
namespace flutter_inappwebview_plugin
{
WebViewEnvironmentManager::WebViewEnvironmentManager(const FlutterInappwebviewWindowsPlugin* plugin)
: plugin(plugin),
ChannelDelegate(plugin->registrar->messenger(), WebViewEnvironmentManager::METHOD_CHANNEL_NAME)
{
windowClass_.lpszClassName = WebViewEnvironmentManager::CLASS_NAME;
windowClass_.lpfnWndProc = &DefWindowProc;
RegisterClass(&windowClass_);
hwnd_ = CreateWindowEx(0, windowClass_.lpszClassName, L"", 0, 0,
0, 0, 0,
plugin->registrar->GetView()->GetNativeWindow(),
nullptr,
windowClass_.hInstance, nullptr);
}
void WebViewEnvironmentManager::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
auto& methodName = method_call.method_name();
if (string_equals(methodName, "create")) {
auto id = get_fl_map_value<std::string>(*arguments, "id");
auto settingsMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "settings");
auto settings = settingsMap.has_value() ? std::make_unique<WebViewEnvironmentSettings>(settingsMap.value()) : nullptr;
createWebViewEnvironment(id, std::move(settings), std::move(result));
}
else if (string_equals(methodName, "getAvailableVersion")) {
auto browserExecutableFolder = get_optional_fl_map_value<std::string>(*arguments, "browserExecutableFolder");
result->Success(make_fl_value(getAvailableVersion(browserExecutableFolder)));
}
else if (string_equals(methodName, "compareBrowserVersions")) {
auto version1 = get_fl_map_value<std::string>(*arguments, "version1");
auto version2 = get_fl_map_value<std::string>(*arguments, "version2");
result->Success(make_fl_value(compareBrowserVersions(version1, version2)));
}
else {
result->NotImplemented();
}
}
void WebViewEnvironmentManager::createWebViewEnvironment(const std::string& id, std::unique_ptr<WebViewEnvironmentSettings> settings, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
auto webViewEnvironment = std::make_unique<WebViewEnvironment>(plugin, id);
webViewEnvironment->create(std::move(settings),
[this, id, result_](HRESULT errorCode)
{
if (succeededOrLog(errorCode)) {
result_->Success(true);
}
else {
result_->Error("0", "Cannot create WebViewEnvironment: " + getHRMessage(errorCode));
if (map_contains(webViewEnvironments, id)) {
webViewEnvironments.erase(id);
}
}
});
webViewEnvironments.insert({ id, std::move(webViewEnvironment) });
}
void WebViewEnvironmentManager::createOrGetDefaultWebViewEnvironment(const std::function<void(WebViewEnvironment*)> completionHandler)
{
if (defaultEnvironment_) {
if (completionHandler) {
completionHandler(defaultEnvironment_.get());
}
return;
}
defaultEnvironment_ = std::make_unique<WebViewEnvironment>(plugin, "-1");
defaultEnvironment_->create(nullptr, [this, completionHandler](HRESULT errorCode)
{
if (succeededOrLog(errorCode)) {
if (completionHandler) {
completionHandler(defaultEnvironment_.get());
}
}
else if (completionHandler) {
defaultEnvironment_ = nullptr;
completionHandler(nullptr);
}
});
}
std::optional<std::string> WebViewEnvironmentManager::getAvailableVersion(std::optional<std::string> browserExecutableFolder)
{
wil::unique_cotaskmem_string versionInfo;
if (succeededOrLog(GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder.has_value() ? utf8_to_wide(browserExecutableFolder.value()).c_str() : nullptr, &versionInfo))) {
return wide_to_utf8(versionInfo.get());
}
return std::nullopt;
}
std::optional<int> WebViewEnvironmentManager::compareBrowserVersions(std::string version1, std::string version2)
{
int result = 0;
if (succeededOrLog(CompareBrowserVersions(utf8_to_wide(version1).c_str(), utf8_to_wide(version2).c_str(), &result))) {
return result;
}
return std::nullopt;
}
WebViewEnvironmentManager::~WebViewEnvironmentManager()
{
debugLog("dealloc WebViewEnvironmentManager");
webViewEnvironments.clear();
plugin = nullptr;
defaultEnvironment_ = nullptr;
if (hwnd_) {
DestroyWindow(hwnd_);
}
}
}