diff --git a/README.md b/README.md index 9278bb61c..9913a25e4 100644 --- a/README.md +++ b/README.md @@ -84,4 +84,4 @@ The _"non-endorsed"_ status means that the plugin is not endorsed by the origina | [**video_player_tizen**](packages/video_player) | 4.0 | ✔️ | ✔️ | ⚠️ | ❌ | Functional limitations,
TV emulator issue | | [**wakelock_tizen**](packages/wakelock) | 4.0 | ✔️ | ✔️ | ❌ | ❌ | Cannot override system settings | | [**wearable_rotary**](packages/wearable_rotary) | 4.0 | ✔️ | ✔️ | ❌ | ❌ | Not applicable for TV | -| [**webview_flutter_tizen**](packages/webview_flutter) | 5.5 | ✔️ | ✔️ | ✔️ | ✔️ | Not for production use | +| [**webview_flutter_tizen**](packages/webview_flutter) | 5.5 | ❌ | ❌ | ✔️ | ❌ | diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index ae58e29f3..c8e1d2318 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.0 + +* Change the backing web engine from LWE to EFL WebKit (EWK). + ## 0.5.6 * Update LWE binary (9af6ea4101d173935fe6e6cd3f2c91ca17ed451e). diff --git a/packages/webview_flutter/README.md b/packages/webview_flutter/README.md index b21eee605..5e9a7c2c8 100644 --- a/packages/webview_flutter/README.md +++ b/packages/webview_flutter/README.md @@ -2,7 +2,8 @@ [![pub package](https://img.shields.io/pub/v/webview_flutter_tizen.svg)](https://pub.dev/packages/webview_flutter_tizen) -The Tizen implementation of [`webview_flutter`](https://github.com/flutter/plugins/tree/main/packages/webview_flutter). +The Tizen implementation of [`webview_flutter`](https://github.com/flutter/plugins/tree/main/packages/webview_flutter) only for Tizen TV devices. +The WebView widget is backed by the EFL WebKit (EWK) on Tizen. ## Required privileges @@ -21,7 +22,7 @@ This package is not an _endorsed_ implementation of `webview_flutter`. Therefore ```yaml dependencies: webview_flutter: ^3.0.4 - webview_flutter_tizen: ^0.5.6 + webview_flutter_tizen: ^0.6.0 ``` ## Example @@ -46,6 +47,4 @@ class WebViewExampleState extends State { ## Supported devices -This plugin is supported on devices running Tizen 5.5 or later. - -The WebView widget is backed by the Lightweight Web Engine (LWE) on Tizen. For a detailed list of features supported by the Lightweight Web Engine, refer to [this page](https://git.tizen.org/cgit/platform/upstream/lightweight-web-engine/tree/docs/Spec.md?h=tizen). +This plugin is supported on Tizen TV devices running Tizen 5.5 or later. diff --git a/packages/webview_flutter/lib/src/platform_view_tizen.dart b/packages/webview_flutter/lib/src/platform_view_tizen.dart deleted file mode 100644 index 66835e57b..000000000 --- a/packages/webview_flutter/lib/src/platform_view_tizen.dart +++ /dev/null @@ -1,659 +0,0 @@ -// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// github.com:flutter/flutter.git@57a688c1f04d56eaa40beeb9f44e549eaf0ce54d -// packages/flutter/lib/src/rendering/platform_view.dart -// packages/flutter/lib/src/widgets/platform_view.dart -// packages/flutter/lib/src/services/platform_views.dart -// Imported from above files, the content has been minimally modified. -// (e.g. Rename keyword 'Android' -> 'Tizen' ) - -// ignore_for_file: public_member_api_docs - -part of '../webview_flutter_tizen.dart'; - -enum _PlatformViewState { - uninitialized, - resizing, - ready, -} - -class TizenView extends StatefulWidget { - const TizenView({ - super.key, - required this.viewType, - this.onPlatformViewCreated, - this.hitTestBehavior = PlatformViewHitTestBehavior.opaque, - this.layoutDirection, - this.gestureRecognizers, - this.creationParams, - this.creationParamsCodec, - this.clipBehavior = Clip.hardEdge, - }) : assert(viewType != null), - assert(hitTestBehavior != null), - assert(creationParams == null || creationParamsCodec != null); - - final String viewType; - final PlatformViewCreatedCallback? onPlatformViewCreated; - final PlatformViewHitTestBehavior hitTestBehavior; - final TextDirection? layoutDirection; - final Set>? gestureRecognizers; - final dynamic creationParams; - final MessageCodec? creationParamsCodec; - final Clip clipBehavior; - - @override - State createState() => _TizenWebViewState(); -} - -class _TizenWebViewState extends State { - int? _id; - late TizenViewController _controller; - TextDirection? _layoutDirection; - bool _initialized = false; - FocusNode? _focusNode; - - static final Set> _emptyRecognizersSet = - >{}; - - @override - Widget build(BuildContext context) { - return Focus( - focusNode: _focusNode, - onFocusChange: _onFocusChange, - child: _TizenPlatformTextureView( - controller: _controller, - hitTestBehavior: widget.hitTestBehavior, - gestureRecognizers: widget.gestureRecognizers ?? _emptyRecognizersSet, - clipBehavior: widget.clipBehavior, - ), - ); - } - - void _initializeOnce() { - if (_initialized) { - return; - } - _initialized = true; - _createNewTizenWebView(); - _focusNode = FocusNode(debugLabel: 'TizenWebView(id: $_id)'); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - final TextDirection newLayoutDirection = _findLayoutDirection(); - final bool didChangeLayoutDirection = - _layoutDirection != newLayoutDirection; - _layoutDirection = newLayoutDirection; - - _initializeOnce(); - if (didChangeLayoutDirection) { - _controller.setLayoutDirection(_layoutDirection!); - } - } - - @override - void didUpdateWidget(TizenView oldWidget) { - super.didUpdateWidget(oldWidget); - - final TextDirection newLayoutDirection = _findLayoutDirection(); - final bool didChangeLayoutDirection = - _layoutDirection != newLayoutDirection; - _layoutDirection = newLayoutDirection; - - if (widget.viewType != oldWidget.viewType) { - _controller.dispose(); - _createNewTizenWebView(); - return; - } - - if (didChangeLayoutDirection) { - _controller.setLayoutDirection(_layoutDirection!); - } - } - - TextDirection _findLayoutDirection() { - assert( - widget.layoutDirection != null || debugCheckHasDirectionality(context)); - return widget.layoutDirection ?? Directionality.of(context); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - void _createNewTizenWebView() { - _id = platformViewsRegistry.getNextPlatformViewId(); - _controller = PlatformViewsServiceTizen.initTizenView( - id: _id!, - viewType: widget.viewType, - layoutDirection: _layoutDirection!, - creationParams: widget.creationParams, - creationParamsCodec: widget.creationParamsCodec, - onFocus: () { - _focusNode!.requestFocus(); - }, - ); - if (widget.onPlatformViewCreated != null) { - _controller - .addOnPlatformViewCreatedListener(widget.onPlatformViewCreated!); - } - } - - void _onFocusChange(bool isFocused) { - if (!_controller.isCreated) { - return; - } - if (!isFocused) { - _controller.clearFocus().catchError((dynamic e) { - if (e is MissingPluginException) { - return; - } - }); - return; - } - SystemChannels.textInput.invokeMethod( - 'TextInput.setPlatformViewClient', - {'platformViewId': _id}, - ).catchError((dynamic e) { - if (e is MissingPluginException) { - return; - } - }); - } -} - -enum _TizenViewState { - waitingForSize, - creating, - created, - disposed, -} - -class TizenViewController extends PlatformViewController { - TizenViewController._({ - required this.viewId, - required String viewType, - required TextDirection layoutDirection, - dynamic creationParams, - MessageCodec? creationParamsCodec, - bool waitingForSize = true, - }) : assert(viewId != null), - assert(viewType != null), - assert(layoutDirection != null), - assert(creationParams == null || creationParamsCodec != null), - _viewType = viewType, - _layoutDirection = layoutDirection, - _creationParams = creationParams, - _creationParamsCodec = creationParamsCodec, - _state = waitingForSize - ? _TizenViewState.waitingForSize - : _TizenViewState.creating; - - @override - final int viewId; - - final String _viewType; - - TextDirection _layoutDirection; - - _TizenViewState _state; - - final dynamic _creationParams; - - final MessageCodec? _creationParamsCodec; - - final List _platformViewCreatedCallbacks = - []; - - static int pointerAction(int pointerId, int action) { - return ((pointerId << 8) & 0xff00) | (action & 0xff); - } - - int? _textureId; - - int? get textureId => _textureId; - - /// The current offset of the platform view. - Offset _off = Offset.zero; - - Future setSize(Size size) async { - assert(_state != _TizenViewState.disposed, - 'Tizen view is disposed. View id: $viewId'); - assert(_state != _TizenViewState.waitingForSize, - 'Tizen view must have an initial size. View id: $viewId'); - assert(size != null); - assert(!size.isEmpty); - - final Map? meta = - await SystemChannels.platform_views.invokeMapMethod( - 'resize', - { - 'id': viewId, - 'width': size.width, - 'height': size.height, - }, - ); - assert(meta != null); - assert(meta!.containsKey('width')); - assert(meta!.containsKey('height')); - return Size(meta!['width']! as double, meta['height']! as double); - } - - Future setOffset(Offset off) async { - if (off == _off) { - return; - } - - if (_state != _TizenViewState.created) { - return; - } - - _off = off; - - await SystemChannels.platform_views.invokeMethod( - 'offset', - { - 'id': viewId, - 'top': off.dy, - 'left': off.dx, - }, - ); - } - - Future _sendCreateMessage({Size? size}) async { - if (size == null) { - return; - } - - assert(!size.isEmpty, - 'trying to create $TizenViewController without setting a valid size.'); - - final Map args = { - 'id': viewId, - 'viewType': _viewType, - 'width': size.width, - 'height': size.height, - 'direction': _layoutDirection == TextDirection.ltr ? 0 : 1, - }; - if (_creationParams != null) { - final ByteData paramsByteData = - _creationParamsCodec!.encodeMessage(_creationParams)!; - args['params'] = Uint8List.view( - paramsByteData.buffer, - 0, - paramsByteData.lengthInBytes, - ); - } - _textureId = - await SystemChannels.platform_views.invokeMethod('create', args); - } - - Future _sendDisposeMessage() { - return SystemChannels.platform_views - .invokeMethod('dispose', { - 'id': viewId, - 'hybrid': false, - }); - } - - @override - Future create({Size? size}) async { - assert(_state != _TizenViewState.disposed, - 'trying to create a disposed Tizen view'); - await _sendCreateMessage(size: size); - - _state = _TizenViewState.created; - for (final PlatformViewCreatedCallback callback - in _platformViewCreatedCallbacks) { - callback(viewId); - } - } - - bool get isCreated => _state == _TizenViewState.created; - - void addOnPlatformViewCreatedListener(PlatformViewCreatedCallback listener) { - assert(listener != null); - assert(_state != _TizenViewState.disposed); - _platformViewCreatedCallbacks.add(listener); - } - - /// Removes a callback added with [addOnPlatformViewCreatedListener]. - void removeOnPlatformViewCreatedListener( - PlatformViewCreatedCallback listener) { - assert(_state != _TizenViewState.disposed); - _platformViewCreatedCallbacks.remove(listener); - } - - Future setLayoutDirection(TextDirection layoutDirection) async { - assert(_state != _TizenViewState.disposed, - 'trying to set a layout direction for a disposed UIView. View id: $viewId'); - - if (layoutDirection == _layoutDirection) { - return; - } - - assert(layoutDirection != null); - _layoutDirection = layoutDirection; - - if (_state == _TizenViewState.waitingForSize) { - return; - } - - await SystemChannels.platform_views - .invokeMethod('setDirection', { - 'id': viewId, - 'direction': layoutDirection == TextDirection.ltr ? 0 : 1, - }); - } - - @override - Future dispatchPointerEvent(PointerEvent event) async { - if (event is PointerHoverEvent) { - return; - } - - int eventType = 0; - if (event is PointerDownEvent) { - eventType = 0; - } else if (event is PointerMoveEvent) { - eventType = 1; - } else if (event is PointerUpEvent) { - eventType = 2; - } else { - throw UnimplementedError('Not Implemented'); - } - await SystemChannels.platform_views - .invokeMethod('touch', { - 'id': viewId, - 'event': [ - eventType, // int, pointer event type - event.buttons, // int, mouse button type (left, right, middle) - event.localPosition.dx, // double, global position x - event.localPosition.dy, // double, global position y - event.localDelta.dx, // double, moved position x - event.localDelta.dy, // double, moved position y - ] - }); - } - - @override - Future clearFocus() { - if (_state != _TizenViewState.created) { - return Future.value(); - } - return SystemChannels.platform_views - .invokeMethod('clearFocus', viewId); - } - - @override - Future dispose() async { - if (_state == _TizenViewState.creating || - _state == _TizenViewState.created) { - await _sendDisposeMessage(); - } - _platformViewCreatedCallbacks.clear(); - _state = _TizenViewState.disposed; - PlatformViewsServiceTizen._instance._focusCallbacks.remove(viewId); - } -} - -class PlatformViewsServiceTizen { - PlatformViewsServiceTizen._() { - SystemChannels.platform_views.setMethodCallHandler(_onMethodCall); - } - static final PlatformViewsServiceTizen _instance = - PlatformViewsServiceTizen._(); - - Future _onMethodCall(MethodCall call) { - switch (call.method) { - case 'viewFocused': - final int id = call.arguments as int; - if (_focusCallbacks.containsKey(id)) { - _focusCallbacks[id]!(); - } - break; - default: - throw UnimplementedError( - "${call.method} was invoked but isn't implemented by PlatformViewsService"); - } - return Future.value(); - } - - final Map _focusCallbacks = {}; - - static TizenViewController initTizenView({ - required int id, - required String viewType, - required TextDirection layoutDirection, - dynamic creationParams, - MessageCodec? creationParamsCodec, - VoidCallback? onFocus, - }) { - assert(id != null); - assert(viewType != null); - assert(layoutDirection != null); - assert(creationParams == null || creationParamsCodec != null); - - final TizenViewController controller = TizenViewController._( - viewId: id, - viewType: viewType, - layoutDirection: layoutDirection, - creationParams: creationParams, - creationParamsCodec: creationParamsCodec, - ); - - _instance._focusCallbacks[id] = onFocus ?? () {}; - return controller; - } -} - -/// A render object for an Tizen view. -/// -/// [RenderTizenView] is responsible for sizing, displaying and passing touch events to Tizen -/// -/// See also: -/// -/// * [PlatformViewsService] which is a service for controlling platform views. -class RenderTizenView extends PlatformViewRenderBox { - /// Creates a render object for an Tizen view. - RenderTizenView({ - required TizenViewController viewController, - required PlatformViewHitTestBehavior hitTestBehavior, - required Set> gestureRecognizers, - Clip clipBehavior = Clip.hardEdge, - }) : assert(viewController != null), - assert(hitTestBehavior != null), - assert(gestureRecognizers != null), - assert(clipBehavior != null), - _viewController = viewController, - _clipBehavior = clipBehavior, - super( - controller: viewController, - hitTestBehavior: hitTestBehavior, - gestureRecognizers: gestureRecognizers) { - updateGestureRecognizers(gestureRecognizers); - _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated); - this.hitTestBehavior = hitTestBehavior; - } - - _PlatformViewState _state = _PlatformViewState.uninitialized; - - Size? _currentTextureSize; - - @override - TizenViewController get controller => _viewController; - - TizenViewController _viewController; - - /// Sets a new Tizen view controller. - /// - /// `viewController` must not be null. - @override - set controller(TizenViewController viewController) { - assert(_viewController != null); - assert(viewController != null); - if (_viewController == viewController) { - return; - } - _viewController.removeOnPlatformViewCreatedListener(_onPlatformViewCreated); - _viewController = viewController; - _sizePlatformView(); - if (_viewController.isCreated) { - markNeedsSemanticsUpdate(); - } - _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated); - } - - /// {@macro flutter.material.Material.clipBehavior} - /// - /// Defaults to [Clip.hardEdge], and must not be null. - Clip get clipBehavior => _clipBehavior; - Clip _clipBehavior = Clip.hardEdge; - set clipBehavior(Clip value) { - assert(value != null); - if (value != _clipBehavior) { - _clipBehavior = value; - markNeedsPaint(); - markNeedsSemanticsUpdate(); - } - } - - void _onPlatformViewCreated(int id) { - markNeedsSemanticsUpdate(); - } - - @override - bool get sizedByParent => true; - - @override - bool get alwaysNeedsCompositing => true; - - @override - bool get isRepaintBoundary => true; - - @override - Size computeDryLayout(BoxConstraints constraints) { - return constraints.biggest; - } - - @override - void performResize() { - super.performResize(); - _sizePlatformView(); - } - - Future _sizePlatformView() async { - if (_state == _PlatformViewState.resizing || size.isEmpty) { - return; - } - - _state = _PlatformViewState.resizing; - markNeedsPaint(); - - Size targetSize; - do { - targetSize = size; - if (_viewController.isCreated) { - _currentTextureSize = await _viewController.setSize(targetSize); - } else { - await _viewController.create(size: targetSize); - _currentTextureSize = targetSize; - } - } while (size != targetSize); - - _state = _PlatformViewState.ready; - markNeedsPaint(); - } - - @override - void paint(PaintingContext context, Offset offset) { - if (_viewController.textureId == null || _currentTextureSize == null) - return; - - final bool isTextureLargerThanWidget = - _currentTextureSize!.width > size.width || - _currentTextureSize!.height > size.height; - if (isTextureLargerThanWidget && clipBehavior != Clip.none) { - _clipRectLayer.layer = context.pushClipRect( - true, - offset, - offset & size, - _paintTexture, - clipBehavior: clipBehavior, - oldLayer: _clipRectLayer.layer, - ); - return; - } - _clipRectLayer.layer = null; - _paintTexture(context, offset); - } - - final LayerHandle _clipRectLayer = - LayerHandle(); - - @override - void dispose() { - _clipRectLayer.layer = null; - super.dispose(); - } - - void _paintTexture(PaintingContext context, Offset offset) { - if (_currentTextureSize == null) { - return; - } - - context.addLayer(TextureLayer( - rect: offset & _currentTextureSize!, - textureId: _viewController.textureId!, - )); - } - - @override - void describeSemanticsConfiguration(SemanticsConfiguration config) { - super.describeSemanticsConfiguration(config); - - config.isSemanticBoundary = true; - - if (_viewController.isCreated) { - config.platformViewId = _viewController.viewId; - } - } -} - -class _TizenPlatformTextureView extends LeafRenderObjectWidget { - const _TizenPlatformTextureView({ - required this.controller, - required this.hitTestBehavior, - required this.gestureRecognizers, - this.clipBehavior = Clip.hardEdge, - }) : assert(controller != null), - assert(hitTestBehavior != null), - assert(gestureRecognizers != null); - - final TizenViewController controller; - final PlatformViewHitTestBehavior hitTestBehavior; - final Set> gestureRecognizers; - final Clip clipBehavior; - - @override - RenderObject createRenderObject(BuildContext context) => RenderTizenView( - viewController: controller, - hitTestBehavior: hitTestBehavior, - gestureRecognizers: gestureRecognizers, - clipBehavior: clipBehavior, - ); - - @override - void updateRenderObject(BuildContext context, RenderTizenView renderObject) { - renderObject.controller = controller; - renderObject.hitTestBehavior = hitTestBehavior; - renderObject.updateGestureRecognizers(gestureRecognizers); - renderObject.clipBehavior = clipBehavior; - } -} diff --git a/packages/webview_flutter/lib/webview_flutter_tizen.dart b/packages/webview_flutter/lib/webview_flutter_tizen.dart index 1470cba7d..70ae2ebf5 100644 --- a/packages/webview_flutter/lib/webview_flutter_tizen.dart +++ b/packages/webview_flutter/lib/webview_flutter_tizen.dart @@ -7,16 +7,14 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_tizen/widgets.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; -part 'src/platform_view_tizen.dart'; - -/// Builds an Tizen webview. +/// Builds a Tizen webview. /// /// This is used as the default implementation for [WebView.platform] on Tizen. It uses a method channel to /// communicate with the platform code. diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 942969c7c..777933d6d 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_tizen description: Tizen implementation of the webview plugin homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/webview_flutter -version: 0.5.6 +version: 0.6.0 environment: sdk: ">=2.17.0 <3.0.0" @@ -19,6 +19,7 @@ flutter: dependencies: flutter: sdk: flutter + flutter_tizen: ^0.2.0 webview_flutter: ^3.0.4 webview_flutter_platform_interface: ^1.8.0 diff --git a/packages/webview_flutter/tizen/inc/lwe/LWEWebView.h b/packages/webview_flutter/tizen/inc/lwe/LWEWebView.h deleted file mode 100644 index a60cb4dab..000000000 --- a/packages/webview_flutter/tizen/inc/lwe/LWEWebView.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (c) 2018-present Samsung Electronics Co., Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -#ifndef __LWEWebView__ -#define __LWEWebView__ - -#ifndef LWE_EXPORT -#ifdef _MSC_VER -#define LWE_EXPORT __declspec(dllexport) -#else -#define LWE_EXPORT __attribute__((visibility("default"))) -#endif -#endif - -#include -#include -#include -#include - -#include "PlatformIntegrationData.h" - -namespace LWE { - -class LWE_EXPORT LWE { - public: - // You must call Initialize function before using WebContainer or WebView - static void Initialize(const char* localStorageDataFilePath, - const char* cookieStoreDataFilePath, - const char* httpCacheDataDirectorypath); - static bool IsInitialized(); - static void Finalize(); -}; - -#define LWE_DEFAULT_FONT_SIZE 16 -#define LWE_MIN_FONT_SIZE 1 -#define LWE_MAX_FONT_SIZE 72 - -enum class WebSecurityMode; - -class LWE_EXPORT CookieManager { - public: - std::string GetCookie(std::string url); - bool HasCookies(); - void ClearCookies(); - - static CookieManager* GetInstance(); - static void Destroy(); - - private: - CookieManager(); - ~CookieManager(); -}; - -class LWE_EXPORT Settings { - public: - Settings(const std::string& defaultUA, const std::string& ua); - std::string GetDefaultUserAgent() const; - std::string GetUserAgentString() const; - std::string GetProxyURL() const; - int GetCacheMode() const; - TTSMode GetTTSMode() const; - std::string GetTTSLanguage() const; - WebSecurityMode GetWebSecurityMode() const; - IdleModeJob GetIdleModeJob() const; - uint32_t GetIdleModeCheckIntervalInMS() const; - void GetBaseBackgroundColor(unsigned char& r, unsigned char& g, - unsigned char& b, unsigned char& a) const; - void GetBaseForegroundColor(unsigned char& r, unsigned char& g, - unsigned char& b, unsigned char& a) const; - bool NeedsDownloadWebFontsEarly() const; - bool UseHttp2() const; - uint32_t NeedsDownScaleImageResourceLargerThan() const; - bool ScrollbarVisible() const; - bool UseExternalPopup() const; - void SetUserAgentString(const std::string& ua); - void SetCacheMode(int mode); - void SetProxyURL(const std::string& proxyURL); - void setDefaultFontSize(int size); - void SetTTSMode(TTSMode value); - void SetTTSLanguage(const std::string& language); - void SetBaseBackgroundColor(unsigned char r, unsigned char g, unsigned char b, - unsigned char a); - void SetBaseForegroundColor(unsigned char r, unsigned char g, unsigned char b, - unsigned char a); - void SetWebSecurityMode(WebSecurityMode value); - void SetIdleModeJob(IdleModeJob j); - void SetIdleModeCheckIntervalInMS(uint32_t intervalInMS); - void SetNeedsDownloadWebFontsEarly(bool b); - void SetUseHttp2(bool b); - void SetNeedsDownScaleImageResourceLargerThan( - uint32_t demention); // Experimental - void SetScrollbarVisible(bool visible); - void SetUseExternalPopup(bool useExternalPopup); - - private: - std::string m_defaultUserAgent; - std::string m_userAgent; - std::string m_proxyURL; - int m_cacheMode; - uint32_t m_defaultFontSize; - TTSMode m_ttsMode; - std::string m_ttsLanguage; - unsigned char m_bgR, m_bgG, m_bgB, m_bgA; - unsigned char m_fgR, m_fgG, m_fgB, m_fgA; - WebSecurityMode m_webSecurityMode; - IdleModeJob m_idleModeJob; // default value is IdleModeJob::IdleModeFull - uint32_t m_idleModeCheckIntervalInMS; // default value is 3000(ms) - bool m_needsDownloadWebFontsEarly; - bool m_useHttp2; // default value is false - uint32_t m_needsDownScaleImageResourceLargerThan; - bool m_scrollbarVisible; - bool m_useExternalPopup; -}; - -class LWE_EXPORT ResourceError { - public: - ResourceError(int code, const std::string& description, - const std::string& url); - int GetErrorCode(); - std::string GetDescription(); - std::string GetUrl(); - - private: - int m_errorCode; - std::string m_description; - std::string m_url; -}; - -class LWE_EXPORT WebContainer { - private: - // use Destroy function instead of using delete operator - ~WebContainer() {} - - public: - // Function set for render to buffer - static WebContainer* Create(unsigned width, unsigned height, - float devicePixelRatio, - const char* defaultFontName, const char* locale, - const char* timezoneID); - struct RenderInfo { - void* updatedBufferAddress; - size_t bufferStride; - }; - - struct ExternalImageInfo { - void* imageAddress; - }; - - struct RenderResult { - size_t updatedX; - size_t updatedY; - size_t updatedWidth; - size_t updatedHeight; - - void* updatedBufferAddress; - size_t bufferImageWidth; - size_t bufferImageHeight; - }; - void RegisterPreRenderingHandler(const std::function& cb); - void RegisterOnRenderedHandler( - const std::function& cb); - - static WebContainer* CreateWithPlatformImage( - unsigned width, unsigned height, - const std::function& prepareImageCb, - const std::function& flushCb, - float devicePixelRatio, const char* defaultFontName, const char* locale, - const char* timezoneID); - // <--- end of function set for render to buffer - - // Function set for render with OpenGL - static WebContainer* CreateGL( - unsigned width, unsigned height, - const std::function& onGLMakeCurrent, - const std::function& - onGLSwapBuffers, - float devicePixelRatio, const char* defaultFontName, const char* locale, - const char* timezoneID); - - static WebContainer* CreateGLWithPlatformImage( - unsigned width, unsigned height, - const std::function& onGLMakeCurrent, - const std::function& - onGLSwapBuffers, - const std::function& prepareImageCb, - const std::function& flushCb, - float devicePixelRatio, const char* defaultFontName, const char* locale, - const char* timezoneID); - - // <--- end of function set for render with OpenGL - - // Function set for headless - static WebContainer* CreateHeadless(unsigned width, unsigned height, - float devicePixelRatio, - const char* defaultFontName, - const char* locale, - const char* timezoneID); - // <--- end of function set for headless - - void AddIdleCallback(void (*callback)(void*), void* data); - size_t AddTimeout(void (*callback)(void*), void* data, size_t timeoutInMS); - void ClearTimeout(size_t handle); - - void RegisterCanRenderingHandler( - const std::function& cb); - - Settings GetSettings(); - void LoadURL(const std::string& url); - std::string GetURL(); - void LoadData(const std::string& data); - void Reload(); - void StopLoading(); - void GoBack(); - void GoForward(); - bool CanGoBack(); - bool CanGoForward(); - void AddJavaScriptInterface( - const std::string& exposedObjectName, const std::string& jsFunctionName, - std::function cb); - std::string EvaluateJavaScript(const std::string& script); - void EvaluateJavaScript(const std::string& script, - std::function cb); - void ClearHistory(); - void Destroy(); - void Pause(); - void Resume(); - - void ResizeTo(size_t width, size_t height); - - void Focus(); - void Blur(); - - void SetSettings(const Settings& settings); - void RemoveJavascriptInterface(const std::string& exposedObjectName, - const std::string& jsFunctionName); - void ClearCache(); - - void RegisterOnReceivedErrorHandler( - const std::function& cb); - void RegisterOnPageParsedHandler( - std::function cb); - void RegisterOnPageLoadedHandler( - std::function cb); - void RegisterOnPageStartedHandler( - const std::function& cb); - void RegisterOnLoadResourceHandler( - const std::function& cb); - void RegisterShouldOverrideUrlLoadingHandler( - const std::function& cb); - void RegisterOnProgressChangedHandler( - const std::function& cb); - void RegisterOnDownloadStartHandler( - const std::function& cb); - - void RegisterShowDropdownMenuHandler( - const std::function*, - int)>& cb); - void RegisterShowAlertHandler( - const std::function& cb); - - void RegisterCustomFileResourceRequestHandlers( - std::function resolveFilePathCallback, - std::function fileOpenCallback, - std::function - fileReadCallback, - std::function fileLengthCallback, - std::function fileCloseCallback); - - void RegisterDebuggerShouldInitHandler( - const std::function& cb); - void RegisterDebuggerShouldContinueWaitingHandler( - const std::function& cb); - - void CallHandler(const std::string& handler, void* param); - - void SetUserAgentString(const std::string& userAgent); - std::string GetUserAgentString(); - void SetCacheMode(int mode); - int GetCacheMode(); - void SetDefaultFontSize(uint32_t size); - uint32_t GetDefaultFontSize(); - - void DispatchMouseMoveEvent(MouseButtonValue button, - MouseButtonsValue buttons, double x, double y); - void DispatchMouseDownEvent(MouseButtonValue button, - MouseButtonsValue buttons, double x, double y); - void DispatchMouseUpEvent(MouseButtonValue button, MouseButtonsValue buttons, - double x, double y); - void DispatchMouseWheelEvent(double x, double y, int delta); - void DispatchKeyDownEvent(KeyValue keyCode); - void DispatchKeyPressEvent(KeyValue keyCode); - void DispatchKeyUpEvent(KeyValue keyCode); - - void DispatchCompositionStartEvent(const std::string& soFarCompositiedString); - void DispatchCompositionUpdateEvent( - const std::string& soFarCompositiedString); - void DispatchCompositionEndEvent(const std::string& soFarCompositiedString); - void RegisterOnShowSoftwareKeyboardIfPossibleHandler( - const std::function& cb); - void RegisterOnHideSoftwareKeyboardIfPossibleHandler( - const std::function& cb); - - void SetUserData(const std::string& key, void* data); - void* GetUserData(const std::string& key); - - std::string GetTitle(); - void ScrollTo(int x, int y); - void ScrollBy(int x, int y); - int GetScrollX(); - int GetScrollY(); - - size_t Width(); - size_t Height(); - - // You can control rendering flow through this function - // If you got callback, you must call `doRenderingFunction` after - void RegisterSetNeedsRenderingCallback( - const std::function& - doRenderingFunction)>& cb); - - protected: - WebContainer(void* webView); - - private: - void* m_impl; -}; - -class LWE_EXPORT WebView { - protected: - // use Destroy function instead of using delete operator - virtual ~WebView() {} - - public: - static WebView* Create(void* win, unsigned x, unsigned y, unsigned width, - unsigned height, float devicePixelRatio, - const char* defaultFontName, const char* locale, - const char* timezoneID); - - virtual void Destroy(); - - Settings GetSettings(); - virtual void LoadURL(const std::string& url); - std::string GetURL(); - void LoadData(const std::string& data); - void Reload(); - void StopLoading(); - void GoBack(); - void GoForward(); - bool CanGoBack(); - bool CanGoForward(); - void Pause(); - void Resume(); - void AddJavaScriptInterface( - const std::string& exposedObjectName, const std::string& jsFunctionName, - std::function cb); - std::string EvaluateJavaScript(const std::string& script); - void EvaluateJavaScript(const std::string& script, - std::function cb); - void ClearHistory(); - void SetSettings(const Settings& settings); - void RemoveJavascriptInterface(const std::string& exposedObjectName, - const std::string& jsFunctionName); - void ClearCache(); - void RegisterOnReceivedErrorHandler( - std::function cb); - void RegisterOnPageParsedHandler( - std::function cb); - void RegisterOnPageLoadedHandler( - std::function cb); - void RegisterOnPageStartedHandler( - std::function cb); - void RegisterOnLoadResourceHandler( - std::function cb); - - void RegisterCustomFileResourceRequestHandlers( - std::function resolveFilePathCallback, - std::function fileOpenCallback, - std::function - fileReadCallback, - std::function fileLengthCallback, - std::function fileCloseCallback); - - void RegisterDebuggerShouldInitHandler( - const std::function& cb); - void RegisterDebuggerShouldContinueWaitingHandler( - const std::function& cb); - - void SetUserData(const std::string& key, void* data); - void* GetUserData(const std::string& key); - - std::string GetTitle(); - void ScrollTo(int x, int y); - void ScrollBy(int x, int y); - int GetScrollX(); - int GetScrollY(); - - virtual void* Unwrap() { - // Some platform returns associated native handle ex) Evas_Object* - return nullptr; - } - virtual void Focus(); - virtual void Blur(); - - protected: - WebView(void* impl) : m_impl(impl) {} - - virtual WebContainer* FetchWebContainer() = 0; - - void* m_impl; -}; - -} // namespace LWE - -#endif diff --git a/packages/webview_flutter/tizen/inc/lwe/PlatformIntegrationData.h b/packages/webview_flutter/tizen/inc/lwe/PlatformIntegrationData.h deleted file mode 100644 index 26716c0a2..000000000 --- a/packages/webview_flutter/tizen/inc/lwe/PlatformIntegrationData.h +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef __PlatformIntegrationData__ -#define __PlatformIntegrationData__ - -namespace LWE { -// This table has same chars with -// ASCII printable char(32-126) -enum KeyValue { - UnidentifiedKey, - AltLeftKey, - AltRightKey, - ControlLeftKey, - ControlRightKey, - CapsLockKey, - FnKey, - FnLockKey, - HyperKey, - MetaKey, - NumLockKey, - ScrollLockKey, - ShiftLeftKey, - ShiftRightKey, - SuperKey, - SymbolKey, - SymbolLockKey, - EnterKey, - TabKey, - ArrowDownKey, - ArrowUpKey, - ArrowLeftKey, - ArrowRightKey, - EndKey, - HomeKey, - PageDownKey, - PageUpKey, - BackspaceKey, - DeleteKey, - InsertKey, - ContextMenuKey, - EscapeKey, - SpaceKey = 32, - ExclamationMarkKey = 33, - DoubleQuoteMarkKey = 34, - SharpMarkKey = 35, - DollarMarkKey = 36, - PercentMarkKey = 37, - AmpersandMarkKey = 38, - SingleQuoteMarkKey = 39, - LeftParenthesisMarkKey = 40, - RightParenthesisMarkKey = 41, - AsteriskMarkKey = 42, - PlusMarkKey = 43, - CommaMarkKey = 44, - MinusMarkKey = 45, - PeriodKey = 46, - SlashKey = 47, - Digit0Key = 48, - Digit1Key, - Digit2Key, - Digit3Key, - Digit4Key, - Digit5Key, - Digit6Key, - Digit7Key, - Digit8Key, - Digit9Key, - ColonMarkKey = 58, - SemiColonMarkKey = 59, - LessThanMarkKey = 60, - EqualitySignKey = 61, - GreaterThanSignKey = 62, - QuestionMarkKey = 63, - AtMarkKey = 64, - AKey = 65, - BKey, - CKey, - DKey, - EKey, - FKey, - GKey, - HKey, - IKey, - JKey, - KKey, - LKey, - MKey, - NKey, - OKey, - PKey, - QKey, - RKey, - SKey, - TKey, - UKey, - VKey, - WKey, - XKey, - YKey, - ZKey, - LeftSquareBracketKey = 91, - BackslashKey = 92, - RightSquareBracketKey = 93, - CaretMarkKey = 94, - UnderScoreMarkKey = 95, - AccentMarkKey = 96, - LowerAKey = 97, - LowerBKey, - LowerCKey, - LowerDKey, - LowerEKey, - LowerFKey, - LowerGKey, - LowerHKey, - LowerIKey, - LowerJKey, - LowerKKey, - LowerLKey, - LowerMKey, - LowerNKey, - LowerOKey, - LowerPKey, - LowerQKey, - LowerRKey, - LowerSKey, - LowerTKey, - LowerUKey, - LowerVKey, - LowerWKey, - LowerXKey, - LowerYKey, - LowerZKey, - LeftCurlyBracketMarkKey = 123, - VerticalBarMarkKey = 124, - RightCurlyBracketMarkKey = 125, - TildeMarkKey = 126, - F1Key, - F2Key, - F3Key, - F4Key, - F5Key, - F6Key, - F7Key, - F8Key, - F9Key, - F10Key, - F11Key, - F12Key, - F13Key, - F14Key, - F15Key, - F16Key, - F17Key, - F18Key, - F19Key, - F20Key, - TVPreviousChannel, - TVChannelDownKey, - TVChannelUpKey, - TVVolumeUpKey, - TVVolumeDownKey, - TVMuteKey, - TVChannelList, - TVChannelGuide, - TVSimpleMenu, - TVReturnKey, - TVExitKey, - TVInfoKey, - TVRedKey, - TVGreenKey, - TVYellowKey, - TVBlueKey, - TVEManual, - TVExtraApp, - TVSearch, - TVPictureSize, - TVSleep, - TVCaption, - TVMore, - TVBTVoice, - TVColor, - TVPlayBack, - TVMenuKey, - MediaFastForwardKey, - MediaPauseKey, - MediaPlayKey, - MediaPlayPauseKey, - MediaRecordKey, - MediaRewindKey, - MediaStopKey, - MediaTrackNextKey, - MediaTrackPreviousKey, - TVKey, - TV3DModeKey, - TVAntennaCableKey, - TVAudioDescriptionKey, - TVAudioDescriptionMixDownKey, - TVAudioDescriptionMixUpKey, - TVContentsMenuKey, - TVDataServiceKey, - TVInputKey, - TVInputComponent1Key, - TVInputComponent2Key, - TVInputComposite1Key, - TVInputComposite2Key, - TVInputHDMI1Key, - TVInputHDMI2Key, - TVInputHDMI3Key, - TVInputHDMI4Key, - TVInputVGA1Key, - TVMediaContextKey, - TVNetworkKey, - TVNumberEntryKey, - TVPowerKey, - TVRadioServiceKey, - TVSatelliteKey, - TVSatelliteBSKey, - TVSatelliteCSKey, - TVSatelliteToggleKey, - TVTerrestrialAnalogKey, - TVTerrestrialDigitalKey, - TVTimerKey, - TVHomeKey, - MediaAppsKey, - MediaAudioTrackKey, - MediaLastKey, - MediaSkipBackwardKey, - MediaSkipForwardKey, - MediaStepBackwardKey, - MediaStepForwardKey, - MediaTopMenuKey, - BrowserBackKey, - BrowserFavoritesKey, - BrowserForwardKey, - BrowserHomeKey, - BrowserRefreshKey, - BrowserSearchKey, - BrowserStopKey, -}; - -enum MouseButtonValue { - NoButton = 0, - LeftButton = 0, - MiddleButton = 1, - RightButton = 2 -}; - -enum MouseButtonsValue { - NoButtonDown = 0, - LeftButtonDown = 1, - RightButtonDown = 1 << 1, - MiddleButtonDown = 1 << 2, -}; - -enum TTSMode { - Default = 0, - Forced = 1, -}; - -enum class WebSecurityMode { Enable = 0, Disable = 1 }; - -enum class IdleModeJob { - ClearDrawnBuffers = 1, - ForceGC = 1 << 1, // it also includes calling malloc_trim(0) - DropDecodedImageBuffer = 1 << 2, - - IdleModeFull = ClearDrawnBuffers | ForceGC | DropDecodedImageBuffer, - IdleModeMiddle = ForceGC, - IdleModeNone = 0, - - IdleModeDefault = IdleModeFull -}; - -constexpr int IdleModeCheckDefaultIntervalInMS{3000}; -} // namespace LWE - -#endif diff --git a/packages/webview_flutter/tizen/lib/aarch64/liblightweight-web-engine.flutter.so b/packages/webview_flutter/tizen/lib/aarch64/liblightweight-web-engine.flutter.so deleted file mode 100755 index 7cba9693f..000000000 Binary files a/packages/webview_flutter/tizen/lib/aarch64/liblightweight-web-engine.flutter.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/lib/aarch64/libtuv.so b/packages/webview_flutter/tizen/lib/aarch64/libtuv.so deleted file mode 100755 index a3323cbd2..000000000 Binary files a/packages/webview_flutter/tizen/lib/aarch64/libtuv.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/lib/armel/liblightweight-web-engine.flutter.so b/packages/webview_flutter/tizen/lib/armel/liblightweight-web-engine.flutter.so deleted file mode 100755 index 927499c52..000000000 Binary files a/packages/webview_flutter/tizen/lib/armel/liblightweight-web-engine.flutter.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/lib/armel/libtuv.so b/packages/webview_flutter/tizen/lib/armel/libtuv.so deleted file mode 100755 index 02915e9a7..000000000 Binary files a/packages/webview_flutter/tizen/lib/armel/libtuv.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/lib/i586/liblightweight-web-engine.flutter.so b/packages/webview_flutter/tizen/lib/i586/liblightweight-web-engine.flutter.so deleted file mode 100755 index a8d48fe03..000000000 Binary files a/packages/webview_flutter/tizen/lib/i586/liblightweight-web-engine.flutter.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/lib/i586/libtuv.so b/packages/webview_flutter/tizen/lib/i586/libtuv.so deleted file mode 100755 index ff0e268cf..000000000 Binary files a/packages/webview_flutter/tizen/lib/i586/libtuv.so and /dev/null differ diff --git a/packages/webview_flutter/tizen/project_def.prop b/packages/webview_flutter/tizen/project_def.prop index c497d3003..ecd814012 100644 --- a/packages/webview_flutter/tizen/project_def.prop +++ b/packages/webview_flutter/tizen/project_def.prop @@ -24,6 +24,6 @@ USER_INC_FILES = USER_CPP_INC_FILES = # Linker options -USER_LIBS = pthread lightweight-web-engine.flutter tuv -USER_LIB_DIRS = lib/${BUILD_ARCH} -USER_LFLAGS = -Wl,-rpath='$$ORIGIN' +USER_LIBS = +USER_LIB_DIRS = +USER_LFLAGS = diff --git a/packages/webview_flutter/tizen/src/buffer_pool.cc b/packages/webview_flutter/tizen/src/buffer_pool.cc index 7e3a2dd0e..ed8fde021 100644 --- a/packages/webview_flutter/tizen/src/buffer_pool.cc +++ b/packages/webview_flutter/tizen/src/buffer_pool.cc @@ -9,7 +9,7 @@ BufferUnit::BufferUnit(int32_t width, int32_t height) { Reset(width, height); } BufferUnit::~BufferUnit() { - if (tbm_surface_) { + if (tbm_surface_ && !use_external_buffer_) { tbm_surface_destroy(tbm_surface_); tbm_surface_ = nullptr; } @@ -19,6 +19,23 @@ BufferUnit::~BufferUnit() { } } +void BufferUnit::UseExternalBuffer() { + if (!use_external_buffer_) { + use_external_buffer_ = true; + if (tbm_surface_) { + tbm_surface_destroy(tbm_surface_); + tbm_surface_ = nullptr; + } + } +} + +void BufferUnit::SetExternalBuffer(tbm_surface_h tbm_surface) { + if (use_external_buffer_) { + tbm_surface_ = tbm_surface; + gpu_surface_->handle = tbm_surface_; + } +} + bool BufferUnit::MarkInUse() { if (!is_used_) { is_used_ = true; diff --git a/packages/webview_flutter/tizen/src/buffer_pool.h b/packages/webview_flutter/tizen/src/buffer_pool.h index e648a7fe9..0128c63ce 100644 --- a/packages/webview_flutter/tizen/src/buffer_pool.h +++ b/packages/webview_flutter/tizen/src/buffer_pool.h @@ -24,6 +24,9 @@ class BufferUnit { bool IsUsed() { return is_used_ && tbm_surface_; } + void UseExternalBuffer(); + void SetExternalBuffer(tbm_surface_h tbm_surface); + tbm_surface_h Surface(); FlutterDesktopGpuSurfaceDescriptor* GpuSurface() { return gpu_surface_; } @@ -35,6 +38,7 @@ class BufferUnit { private: bool is_used_ = false; + bool use_external_buffer_ = false; int32_t width_ = 0; int32_t height_ = 0; tbm_surface_h tbm_surface_ = nullptr; diff --git a/packages/webview_flutter/tizen/src/ewk_internal_api_binding.cc b/packages/webview_flutter/tizen/src/ewk_internal_api_binding.cc new file mode 100644 index 000000000..82d7757a6 --- /dev/null +++ b/packages/webview_flutter/tizen/src/ewk_internal_api_binding.cc @@ -0,0 +1,64 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ewk_internal_api_binding.h" + +#include + +EwkInternalApiBinding::EwkInternalApiBinding() { + handle_ = dlopen("libchromium-ewk.so", RTLD_LAZY); +} + +EwkInternalApiBinding::~EwkInternalApiBinding() { + if (handle_) { + dlclose(handle_); + } +} + +bool EwkInternalApiBinding::Initialize() { + if (handle_ == nullptr) { + return false; + } + + // ewk_view + view.SetBackgroundColor = reinterpret_cast( + dlsym(handle_, "ewk_view_bg_color_set")); + view.FeedTouchEvent = reinterpret_cast( + dlsym(handle_, "ewk_view_feed_touch_event")); + view.SendKeyEvent = reinterpret_cast( + dlsym(handle_, "ewk_view_send_key_event")); + view.OffscreenRenderingEnabledSet = + reinterpret_cast( + dlsym(handle_, "ewk_view_offscreen_rendering_enabled_set")); + view.ImeWindowSet = reinterpret_cast( + dlsym(handle_, "ewk_view_ime_window_set")); + view.KeyEventsEnabledSet = reinterpret_cast( + dlsym(handle_, "ewk_view_key_events_enabled_set")); + + // ewk_main + main.SetArguments = reinterpret_cast( + dlsym(handle_, "ewk_set_arguments")); + + // ewk_settings + settings.ImePanelEnabledSet = + reinterpret_cast( + dlsym(handle_, "ewk_settings_ime_panel_enabled_set")); + + // ewk_console_message + console_message.LevelGet = reinterpret_cast( + dlsym(handle_, "ewk_console_message_level_get")); + console_message.TextGet = reinterpret_cast( + dlsym(handle_, "ewk_console_message_text_get")); + console_message.LineGet = reinterpret_cast( + dlsym(handle_, "ewk_console_message_line_get")); + console_message.SourceGet = reinterpret_cast( + dlsym(handle_, "ewk_console_message_source_get")); + + return view.SetBackgroundColor && view.FeedTouchEvent && view.SendKeyEvent && + view.OffscreenRenderingEnabledSet && view.ImeWindowSet && + view.KeyEventsEnabledSet && main.SetArguments && + settings.ImePanelEnabledSet && console_message.LevelGet && + console_message.TextGet && console_message.LineGet && + console_message.SourceGet; +} diff --git a/packages/webview_flutter/tizen/src/ewk_internal_api_binding.h b/packages/webview_flutter/tizen/src/ewk_internal_api_binding.h new file mode 100644 index 000000000..f4a8971f4 --- /dev/null +++ b/packages/webview_flutter/tizen/src/ewk_internal_api_binding.h @@ -0,0 +1,117 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_EWK_INTERNAL_API_BINDING_H_ +#define FLUTTER_PLUGIN_EWK_INTERNAL_API_BINDING_H_ + +#include + +typedef enum { + EWK_TOUCH_START, + EWK_TOUCH_MOVE, + EWK_TOUCH_END, + EWK_TOUCH_CANCEL +} Ewk_Touch_Event_Type; + +typedef struct _Ewk_Touch_Point Ewk_Touch_Point; + +struct _Ewk_Touch_Point { + int id; + int x; + int y; + Evas_Touch_Point_State state; +}; + +typedef Eina_Bool (*EwkViewBgColorSetFnPtr)(Evas_Object* obj, int r, int g, + int b, int a); +typedef Eina_Bool (*EwkViewFeedTouchEventFnPtr)(Evas_Object* obj, + Ewk_Touch_Event_Type type, + const Eina_List* points, + const Evas_Modifier* modifiers); +typedef Eina_Bool (*EwkViewSendKeyEventFnPtr)(Evas_Object* obj, void* key_event, + Eina_Bool is_press); +typedef void (*EwkViewOffscreenRenderingEnabledSetFnPtr)(Evas_Object* obj, + Eina_Bool enabled); +typedef void (*EwkViewImeWindowSetFnPtr)(Evas_Object* obj, void* window); +typedef Eina_Bool (*EwkViewKeyEventsEnabledSetFnPtr)(Evas_Object* obj, + Eina_Bool enabled); + +typedef struct { + EwkViewBgColorSetFnPtr SetBackgroundColor = nullptr; + EwkViewFeedTouchEventFnPtr FeedTouchEvent = nullptr; + EwkViewSendKeyEventFnPtr SendKeyEvent = nullptr; + EwkViewOffscreenRenderingEnabledSetFnPtr OffscreenRenderingEnabledSet = + nullptr; + EwkViewImeWindowSetFnPtr ImeWindowSet = nullptr; + EwkViewKeyEventsEnabledSetFnPtr KeyEventsEnabledSet = nullptr; +} EwkViewProcTable; + +typedef void (*EwkSetArgumentsFnPtr)(int argc, char** argv); + +typedef struct { + EwkSetArgumentsFnPtr SetArguments = nullptr; +} EwkMainProcTable; + +typedef struct Ewk_Settings Ewk_Settings; +typedef void (*EwkSettingsImePanelEnabledSetFnPtr)(Ewk_Settings* settings, + Eina_Bool enabled); + +typedef struct { + EwkSettingsImePanelEnabledSetFnPtr ImePanelEnabledSet = nullptr; +} EWKSettingsProcTable; + +typedef struct _Ewk_Console_Message Ewk_Console_Message; + +typedef enum { + EWK_CONSOLE_MESSAGE_LEVEL_NULL, + EWK_CONSOLE_MESSAGE_LEVEL_LOG, + EWK_CONSOLE_MESSAGE_LEVEL_WARNING, + EWK_CONSOLE_MESSAGE_LEVEL_ERROR, + EWK_CONSOLE_MESSAGE_LEVEL_DEBUG, + EWK_CONSOLE_MESSAGE_LEVEL_INFO, +} Ewk_Console_Message_Level; + +typedef Ewk_Console_Message_Level (*EwkConsoleMessageLevelGetFnPtr)( + const Ewk_Console_Message* message); +typedef Eina_Stringshare* (*EwkConsoleMessageTextGetFnPtr)( + const Ewk_Console_Message* message); +typedef unsigned (*EwkConsoleMessageLineGetFnPtr)( + const Ewk_Console_Message* message); +typedef Eina_Stringshare* (*EwkConsoleMessageSourceGetFnPtr)( + const Ewk_Console_Message* message); + +typedef struct { + EwkConsoleMessageLevelGetFnPtr LevelGet = nullptr; + EwkConsoleMessageTextGetFnPtr TextGet = nullptr; + EwkConsoleMessageLineGetFnPtr LineGet = nullptr; + EwkConsoleMessageSourceGetFnPtr SourceGet = nullptr; +} EWKConsoleMessageProcTable; + +class EwkInternalApiBinding { + public: + static EwkInternalApiBinding& GetInstance() { + static EwkInternalApiBinding instance = EwkInternalApiBinding(); + return instance; + } + + ~EwkInternalApiBinding(); + + EwkInternalApiBinding(const EwkInternalApiBinding&) = delete; + + EwkInternalApiBinding& operator=(const EwkInternalApiBinding&) = delete; + + bool Initialize(); + + EwkViewProcTable view; + EwkMainProcTable main; + EWKSettingsProcTable settings; + EWKConsoleMessageProcTable console_message; + + private: + EwkInternalApiBinding(); + + void* handle_ = nullptr; +}; + +#endif // FLUTTER_PLUGIN_EWK_INTERNAL_API_BINDING_H_ diff --git a/packages/webview_flutter/tizen/src/webview.cc b/packages/webview_flutter/tizen/src/webview.cc index 934defcc4..7144bbade 100644 --- a/packages/webview_flutter/tizen/src/webview.cc +++ b/packages/webview_flutter/tizen/src/webview.cc @@ -4,117 +4,76 @@ #include "webview.h" +#include #include #include #include -#include #include -#include -#include - #include "buffer_pool.h" +#include "ewk_internal_api_binding.h" #include "log.h" -#include "lwe/LWEWebView.h" -#include "lwe/PlatformIntegrationData.h" #include "webview_factory.h" -static constexpr size_t kBufferPoolSize = 5; +namespace { + +typedef flutter::MethodCall FlMethodCall; +typedef flutter::MethodResult FlMethodResult; +typedef flutter::MethodChannel FlMethodChannel; -extern "C" size_t LWE_EXPORT createWebViewInstance( - unsigned x, unsigned y, unsigned width, unsigned height, - float devicePixelRatio, const char* defaultFontName, const char* locale, - const char* timezoneID, - const std::function<::LWE::WebContainer::ExternalImageInfo(void)>& - prepareImageCb, - const std::function& flushCb, - bool useSWBackend); +constexpr size_t kBufferPoolSize = 5; +constexpr char kEwkInstance[] = "ewk_instance"; class NavigationRequestResult : public flutter::MethodResult { public: - NavigationRequestResult(std::string url, WebView* webview) - : url_(url), webview_(webview) {} + NavigationRequestResult(WebView* webview) : webview_(webview) {} void SuccessInternal(const flutter::EncodableValue* should_load) override { if (std::holds_alternative(*should_load)) { if (std::get(*should_load)) { - LoadUrl(); + webview_->Resume(); + return; } } + webview_->Stop(); } void ErrorInternal(const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details) override { + webview_->Stop(); LOG_ERROR("The request unexpectedly completed with an error."); } void NotImplementedInternal() override { + webview_->Stop(); LOG_ERROR("The target method was unexpectedly unimplemented."); } private: - void LoadUrl() { - if (webview_ && webview_->GetWebViewInstance()) { - webview_->GetWebViewInstance()->LoadURL(url_); - } - } - - std::string url_; WebView* webview_; }; -enum class ResourceErrorType { - NoError, - UnknownError, - HostLookupError, - UnsupportedAuthSchemeError, - AuthenticationError, - ProxyAuthenticationError, - ConnectError, - IOError, - TimeoutError, - RedirectLoopError, - UnsupportedSchemeError, - FailedSSLHandshakeError, - BadURLError, - FileError, - FileNotFoundError, - TooManyRequestError, -}; - -static std::string ErrorCodeToString(int error_code) { - switch (ResourceErrorType(error_code)) { - case ResourceErrorType::AuthenticationError: +std::string ErrorCodeToString(int error_code) { + switch (error_code) { + case EWK_ERROR_CODE_AUTHENTICATION: return "authentication"; - case ResourceErrorType::BadURLError: + case EWK_ERROR_CODE_BAD_URL: return "badUrl"; - case ResourceErrorType::ConnectError: - return "connect"; - case ResourceErrorType::FailedSSLHandshakeError: + case EWK_ERROR_CODE_FAILED_TLS_HANDSHAKE: return "failedSslHandshake"; - case ResourceErrorType::FileError: + case EWK_ERROR_CODE_FAILED_FILE_IO: return "file"; - case ResourceErrorType::FileNotFoundError: - return "fileNotFound"; - case ResourceErrorType::HostLookupError: + case EWK_ERROR_CODE_CANT_LOOKUP_HOST: return "hostLookup"; - case ResourceErrorType::IOError: - return "io"; - case ResourceErrorType::ProxyAuthenticationError: - return "proxyAuthentication"; - case ResourceErrorType::RedirectLoopError: - return "redirectLoop"; - case ResourceErrorType::TimeoutError: + case EWK_ERROR_CODE_REQUEST_TIMEOUT: return "timeout"; - case ResourceErrorType::TooManyRequestError: + case EWK_ERROR_CODE_TOO_MANY_REQUESTS: return "tooManyRequests"; - case ResourceErrorType::UnknownError: + case EWK_ERROR_CODE_UNKNOWN: return "unknown"; - case ResourceErrorType::UnsupportedAuthSchemeError: - return "unsupportedAuthScheme"; - case ResourceErrorType::UnsupportedSchemeError: + case EWK_ERROR_CODE_UNSUPPORTED_SCHEME: return "unsupportedScheme"; default: LOG_ERROR("Unknown error type: %d", error_code); @@ -123,8 +82,8 @@ static std::string ErrorCodeToString(int error_code) { } template -static bool GetValueFromEncodableMap(const flutter::EncodableValue* arguments, - std::string key, T* out) { +bool GetValueFromEncodableMap(const flutter::EncodableValue* arguments, + std::string key, T* out) { if (auto* map = std::get_if(arguments)) { auto iter = map->find(flutter::EncodableValue(key)); if (iter != map->end() && !iter->second.IsNull()) { @@ -137,34 +96,24 @@ static bool GetValueFromEncodableMap(const flutter::EncodableValue* arguments, return false; } -static bool IsRunningOnEmulator() { - bool result = false; - char* value = nullptr; - int ret = system_info_get_platform_string( - "http://tizen.org/system/model_name", &value); - if (ret == SYSTEM_INFO_ERROR_NONE && strcmp(value, "Emulator") == 0) { - result = true; - } - if (value) { - free(value); - } - return result; -} +} // namespace WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, flutter::TextureRegistrar* texture_registrar, double width, - double height, const flutter::EncodableValue& params) + double height, const flutter::EncodableValue& params, + void* win) : PlatformView(registrar, view_id, nullptr), texture_registrar_(texture_registrar), width_(width), - height_(height) { - use_sw_backend_ = IsRunningOnEmulator(); - if (use_sw_backend_) { - tbm_pool_ = std::make_unique(width, height); - } else { - tbm_pool_ = std::make_unique(width, height, kBufferPoolSize); + height_(height), + win_(win) { + if (!EwkInternalApiBinding::GetInstance().Initialize()) { + LOG_ERROR("Failed to Initialize EWK internal APIs."); + return; } + tbm_pool_ = std::make_unique(width, height); + texture_variant_ = std::make_unique(flutter::GpuSurfaceTexture( kFlutterDesktopGpuSurfaceTypeNone, @@ -176,7 +125,7 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, InitWebView(); - channel_ = std::make_unique>( + channel_ = std::make_unique( GetPluginRegistrar()->messenger(), GetChannelName(), &flutter::StandardMethodCodec::GetInstance()); channel_->SetMethodCallHandler( @@ -184,11 +133,9 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, webview->HandleMethodCall(call, std::move(result)); }); - auto cookie_channel = - std::make_unique>( - GetPluginRegistrar()->messenger(), - "plugins.flutter.io/cookie_manager", - &flutter::StandardMethodCodec::GetInstance()); + auto cookie_channel = std::make_unique( + GetPluginRegistrar()->messenger(), "plugins.flutter.io/cookie_manager", + &flutter::StandardMethodCodec::GetInstance()); cookie_channel->SetMethodCallHandler( [webview = this](const auto& call, auto result) { webview->HandleCookieMethodCall(call, std::move(result)); @@ -201,10 +148,9 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, int color; if (GetValueFromEncodableMap(¶ms, "backgroundColor", &color)) { - LWE::Settings settings = webview_instance_->GetSettings(); - settings.SetBaseBackgroundColor(color >> 16 & 0xff, color >> 8 & 0xff, - color & 0xff, color >> 24 & 0xff); - webview_instance_->SetSettings(settings); + EwkInternalApiBinding::GetInstance().view.SetBackgroundColor( + webview_instance_, color >> 16 & 0xff, color >> 8 & 0xff, color & 0xff, + color >> 24 & 0xff); } flutter::EncodableMap settings; @@ -225,68 +171,9 @@ WebView::WebView(flutter::PluginRegistrar* registrar, int view_id, std::string user_agent; if (GetValueFromEncodableMap(¶ms, "userAgent", &user_agent)) { - LWE::Settings settings = webview_instance_->GetSettings(); - settings.SetUserAgentString(user_agent); - webview_instance_->SetSettings(settings); + ewk_view_user_agent_set(webview_instance_, user_agent.c_str()); } - - webview_instance_->RegisterOnPageStartedHandler( - [this](LWE::WebContainer* container, const std::string& url) { - flutter::EncodableMap args = { - {flutter::EncodableValue("url"), flutter::EncodableValue(url)}}; - channel_->InvokeMethod("onPageStarted", - std::make_unique(args)); - }); - webview_instance_->RegisterOnPageLoadedHandler( - [this](LWE::WebContainer* container, const std::string& url) { - flutter::EncodableMap args = { - {flutter::EncodableValue("url"), flutter::EncodableValue(url)}}; - channel_->InvokeMethod("onPageFinished", - std::make_unique(args)); - }); - webview_instance_->RegisterOnProgressChangedHandler( - [this](LWE::WebContainer* container, int progress) { - if (!has_progress_tracking_) { - return; - } - flutter::EncodableMap args = {{flutter::EncodableValue("progress"), - flutter::EncodableValue(progress)}}; - channel_->InvokeMethod("onProgress", - std::make_unique(args)); - }); - webview_instance_->RegisterOnReceivedErrorHandler( - [this](LWE::WebContainer* container, LWE::ResourceError error) { - flutter::EncodableMap args = { - {flutter::EncodableValue("errorCode"), - flutter::EncodableValue(error.GetErrorCode())}, - {flutter::EncodableValue("description"), - flutter::EncodableValue(error.GetDescription())}, - {flutter::EncodableValue("errorType"), - flutter::EncodableValue(ErrorCodeToString(error.GetErrorCode()))}, - {flutter::EncodableValue("failingUrl"), - flutter::EncodableValue(error.GetUrl())}, - }; - channel_->InvokeMethod("onWebResourceError", - std::make_unique(args)); - }); - webview_instance_->RegisterShouldOverrideUrlLoadingHandler( - [this](LWE::WebContainer* view, const std::string& url) -> bool { - if (!has_navigation_delegate_) { - return false; - } - flutter::EncodableMap args = { - {flutter::EncodableValue("url"), flutter::EncodableValue(url)}, - {flutter::EncodableValue("isForMainFrame"), - flutter::EncodableValue(true)}, - }; - auto result = std::make_unique(url, this); - channel_->InvokeMethod("navigationRequest", - std::make_unique(args), - std::move(result)); - return true; - }); - - webview_instance_->LoadURL(url); + ewk_view_url_set(webview_instance_, url.c_str()); } void WebView::ApplySettings(const flutter::EncodableMap& settings) { @@ -294,7 +181,6 @@ void WebView::ApplySettings(const flutter::EncodableMap& settings) { if (std::holds_alternative(key)) { std::string string_key = std::get(key); if (string_key == "jsMode") { - // NOTE: Not supported by LWE on Tizen. } else if (string_key == "hasNavigationDelegate") { if (std::holds_alternative(value)) { has_navigation_delegate_ = std::get(value); @@ -304,19 +190,14 @@ void WebView::ApplySettings(const flutter::EncodableMap& settings) { has_progress_tracking_ = std::get(value); } } else if (string_key == "debuggingEnabled") { - // NOTE: Not supported by LWE on Tizen. } else if (string_key == "gestureNavigationEnabled") { - // NOTE: Not supported by LWE on Tizen. } else if (string_key == "allowsInlineMediaPlayback") { - // no-op inline media playback is always allowed on Tizen. } else if (string_key == "userAgent") { if (std::holds_alternative(value)) { - LWE::Settings settings = webview_instance_->GetSettings(); - settings.SetUserAgentString(std::get(value)); - webview_instance_->SetSettings(settings); + ewk_view_user_agent_set(webview_instance_, + std::get(value).c_str()); } } else if (string_key == "zoomEnabled") { - // NOTE: Not supported by LWE on Tizen. } else { LOG_WARN("Unknown settings key: %s", string_key.c_str()); } @@ -333,18 +214,8 @@ void WebView::ApplySettings(const flutter::EncodableMap& settings) { */ void WebView::RegisterJavaScriptChannelName(const std::string& name) { LOG_DEBUG("Register a JavaScript channel: %s", name.c_str()); - - auto on_message = [this, name](const std::string& message) -> std::string { - LOG_DEBUG("JavaScript channel message: %s", message.c_str()); - flutter::EncodableMap args = { - {flutter::EncodableValue("channel"), flutter::EncodableValue(name)}, - {flutter::EncodableValue("message"), flutter::EncodableValue(message)}, - }; - channel_->InvokeMethod("javascriptChannelMessage", - std::make_unique(args)); - return "success"; - }; - webview_instance_->AddJavaScriptInterface(name, "postMessage", on_message); + ewk_view_javascript_message_handler_add( + webview_instance_, &WebView::OnJavaScriptMessage, name.c_str()); } WebView::~WebView() { Dispose(); } @@ -354,12 +225,19 @@ std::string WebView::GetChannelName() { } void WebView::Dispose() { + evas_object_smart_callback_del(webview_instance_, "offscreen,frame,rendered", + &WebView::OnFrameRendered); + evas_object_smart_callback_del(webview_instance_, "load,started", + &WebView::OnLoadStarted); + evas_object_smart_callback_del(webview_instance_, "load,finished", + &WebView::OnLoadFinished); + evas_object_smart_callback_del(webview_instance_, "load,error", + &WebView::OnLoadError); + evas_object_smart_callback_del(webview_instance_, "console,message", + &WebView::OnConsoleMessage); + evas_object_smart_callback_del(webview_instance_, "policy,navigation,decide", + &WebView::OnNavigationPolicy); texture_registrar_->UnregisterTexture(GetTextureId()); - - if (webview_instance_) { - webview_instance_->Destroy(); - webview_instance_ = nullptr; - } } void WebView::Resize(double width, double height) { @@ -371,225 +249,37 @@ void WebView::Resize(double width, double height) { } tbm_pool_->Prepare(width_, height_); - webview_instance_->ResizeTo(width_, height_); + evas_object_resize(webview_instance_, width_, height_); } void WebView::Touch(int type, int button, double x, double y, double dx, double dy) { + Ewk_Touch_Event_Type mouse_event_type = EWK_TOUCH_START; + Evas_Touch_Point_State state = EVAS_TOUCH_POINT_DOWN; if (type == 0) { // down event - webview_instance_->DispatchMouseDownEvent( - LWE::MouseButtonValue::LeftButton, - LWE::MouseButtonsValue::LeftButtonDown, x, y); - is_mouse_lbutton_down_ = true; + mouse_event_type = EWK_TOUCH_START; + state = EVAS_TOUCH_POINT_DOWN; } else if (type == 1) { // move event - webview_instance_->DispatchMouseMoveEvent( - is_mouse_lbutton_down_ ? LWE::MouseButtonValue::LeftButton - : LWE::MouseButtonValue::NoButton, - is_mouse_lbutton_down_ ? LWE::MouseButtonsValue::LeftButtonDown - : LWE::MouseButtonsValue::NoButtonDown, - x, y); + mouse_event_type = EWK_TOUCH_MOVE; + state = EVAS_TOUCH_POINT_MOVE; + } else if (type == 2) { // up event - webview_instance_->DispatchMouseUpEvent( - LWE::MouseButtonValue::NoButton, LWE::MouseButtonsValue::NoButtonDown, - x, y); - is_mouse_lbutton_down_ = false; + mouse_event_type = EWK_TOUCH_END; + state = EVAS_TOUCH_POINT_UP; } else { - LOG_WARN("Unknown touch event type: %d", type); - } -} - -static LWE::KeyValue KeyToKeyValue(const std::string& key, - bool is_shift_pressed) { - if (key == "Left") { - return LWE::KeyValue::ArrowLeftKey; - } else if (key == "Right") { - return LWE::KeyValue::ArrowRightKey; - } else if (key == "Up") { - return LWE::KeyValue::ArrowUpKey; - } else if (key == "Down") { - return LWE::KeyValue::ArrowDownKey; - } else if (key == "space") { - return LWE::KeyValue::SpaceKey; - } else if (key == "Select") { - return LWE::KeyValue::EnterKey; - } else if (key == "Return") { - return LWE::KeyValue::EnterKey; - } else if (key == "Tab") { - return LWE::KeyValue::TabKey; - } else if (key == "BackSpace") { - return LWE::KeyValue::BackspaceKey; - } else if (key == "Escape") { - return LWE::KeyValue::EscapeKey; - } else if (key == "Delete") { - return LWE::KeyValue::DeleteKey; - } else if (key == "at") { - return LWE::KeyValue::AtMarkKey; - } else if (key == "minus") { - if (is_shift_pressed) { - return LWE::KeyValue::UnderScoreMarkKey; - } else { - return LWE::KeyValue::MinusMarkKey; - } - } else if (key == "equal") { - if (is_shift_pressed) { - return LWE::KeyValue::PlusMarkKey; - } else { - return LWE::KeyValue::EqualitySignKey; - } - } else if (key == "bracketleft") { - if (is_shift_pressed) { - return LWE::KeyValue::LeftCurlyBracketMarkKey; - } else { - return LWE::KeyValue::LeftSquareBracketKey; - } - } else if (key == "bracketright") { - if (is_shift_pressed) { - return LWE::KeyValue::RightCurlyBracketMarkKey; - } else { - return LWE::KeyValue::RightSquareBracketKey; - } - } else if (key == "semicolon") { - if (is_shift_pressed) { - return LWE::KeyValue::ColonMarkKey; - } else { - return LWE::KeyValue::SemiColonMarkKey; - } - } else if (key == "apostrophe") { - if (is_shift_pressed) { - return LWE::KeyValue::DoubleQuoteMarkKey; - } else { - return LWE::KeyValue::SingleQuoteMarkKey; - } - } else if (key == "comma") { - if (is_shift_pressed) { - return LWE::KeyValue::LessThanMarkKey; - } else { - return LWE::KeyValue::CommaMarkKey; - } - } else if (key == "period") { - if (is_shift_pressed) { - return LWE::KeyValue::GreaterThanSignKey; - } else { - return LWE::KeyValue::PeriodKey; - } - } else if (key == "slash") { - if (is_shift_pressed) { - return LWE::KeyValue::QuestionMarkKey; - } else { - return LWE::KeyValue::SlashKey; - } - } else if (key.length() == 1) { - const char ch = key.at(0); - if (ch >= '0' && ch <= '9') { - if (is_shift_pressed) { - switch (ch) { - case '1': - return LWE::KeyValue::ExclamationMarkKey; - case '2': - return LWE::KeyValue::AtMarkKey; - case '3': - return LWE::KeyValue::SharpMarkKey; - case '4': - return LWE::KeyValue::DollarMarkKey; - case '5': - return LWE::KeyValue::PercentMarkKey; - case '6': - return LWE::KeyValue::CaretMarkKey; - case '7': - return LWE::KeyValue::AmpersandMarkKey; - case '8': - return LWE::KeyValue::AsteriskMarkKey; - case '9': - return LWE::KeyValue::LeftParenthesisMarkKey; - case '0': - return LWE::KeyValue::RightParenthesisMarkKey; - } - } - return LWE::KeyValue(LWE::KeyValue::Digit0Key + ch - '0'); - } else if (ch >= 'a' && ch <= 'z') { - if (is_shift_pressed) { - return LWE::KeyValue(LWE::KeyValue::LowerAKey + ch - 'a' - 32); - } else { - return LWE::KeyValue(LWE::KeyValue::LowerAKey + ch - 'a'); - } - } else if (ch >= 'A' && ch <= 'Z') { - if (is_shift_pressed) { - return LWE::KeyValue(LWE::KeyValue::AKey + ch - 'A' + 32); - } else { - return LWE::KeyValue(LWE::KeyValue::AKey + ch - 'A'); - } - } - } else if (key == "XF86AudioRaiseVolume") { - return LWE::KeyValue::TVVolumeUpKey; - } else if (key == "XF86AudioLowerVolume") { - return LWE::KeyValue::TVVolumeDownKey; - } else if (key == "XF86AudioMute") { - return LWE::KeyValue::TVMuteKey; - } else if (key == "XF86RaiseChannel") { - return LWE::KeyValue::TVChannelUpKey; - } else if (key == "XF86LowerChannel") { - return LWE::KeyValue::TVChannelDownKey; - } else if (key == "XF86AudioRewind") { - return LWE::KeyValue::MediaTrackPreviousKey; - } else if (key == "XF86AudioNext") { - return LWE::KeyValue::MediaTrackNextKey; - } else if (key == "XF86AudioPause") { - return LWE::KeyValue::MediaPauseKey; - } else if (key == "XF86AudioRecord") { - return LWE::KeyValue::MediaRecordKey; - } else if (key == "XF86AudioPlay") { - return LWE::KeyValue::MediaPlayKey; - } else if (key == "XF86AudioStop") { - return LWE::KeyValue::MediaStopKey; - } else if (key == "XF86Info") { - return LWE::KeyValue::TVInfoKey; - } else if (key == "XF86Back") { - return LWE::KeyValue::TVReturnKey; - } else if (key == "XF86Red") { - return LWE::KeyValue::TVRedKey; - } else if (key == "XF86Green") { - return LWE::KeyValue::TVGreenKey; - } else if (key == "XF86Yellow") { - return LWE::KeyValue::TVYellowKey; - } else if (key == "XF86Blue") { - return LWE::KeyValue::TVBlueKey; - } else if (key == "XF86SysMenu") { - return LWE::KeyValue::TVMenuKey; - } else if (key == "XF86Home") { - return LWE::KeyValue::TVHomeKey; - } else if (key == "XF86Exit") { - return LWE::KeyValue::TVExitKey; - } else if (key == "XF86PreviousChannel") { - return LWE::KeyValue::TVPreviousChannel; - } else if (key == "XF86ChannelList") { - return LWE::KeyValue::TVChannelList; - } else if (key == "XF86ChannelGuide") { - return LWE::KeyValue::TVChannelGuide; - } else if (key == "XF86SimpleMenu") { - return LWE::KeyValue::TVSimpleMenu; - } else if (key == "XF86EManual") { - return LWE::KeyValue::TVEManual; - } else if (key == "XF86ExtraApp") { - return LWE::KeyValue::TVExtraApp; - } else if (key == "XF86Search") { - return LWE::KeyValue::TVSearch; - } else if (key == "XF86PictureSize") { - return LWE::KeyValue::TVPictureSize; - } else if (key == "XF86Sleep") { - return LWE::KeyValue::TVSleep; - } else if (key == "XF86Caption") { - return LWE::KeyValue::TVCaption; - } else if (key == "XF86More") { - return LWE::KeyValue::TVMore; - } else if (key == "XF86BTVoice") { - return LWE::KeyValue::TVBTVoice; - } else if (key == "XF86Color") { - return LWE::KeyValue::TVColor; - } else if (key == "XF86PlayBack") { - return LWE::KeyValue::TVPlayBack; + // TODO: Not implemented } - LOG_WARN("Unknown key name: %s", key.c_str()); - return LWE::KeyValue::UnidentifiedKey; + Eina_List* pointList = 0; + Ewk_Touch_Point* point = new Ewk_Touch_Point; + point->id = 0; + point->x = x; + point->y = y; + point->state = state; + pointList = eina_list_append(pointList, point); + + EwkInternalApiBinding::GetInstance().view.FeedTouchEvent( + webview_instance_, mouse_event_type, pointList, 0); + eina_list_free(pointList); } bool WebView::SendKey(const char* key, const char* string, const char* compose, @@ -598,95 +288,96 @@ bool WebView::SendKey(const char* key, const char* string, const char* compose, return false; } - bool is_shift_pressed = modifiers & 1; - - struct Param { - LWE::WebContainer* webview_instance; - LWE::KeyValue key_value; - bool is_down; - }; - - Param* param = new Param(); - param->webview_instance = webview_instance_; - param->key_value = KeyToKeyValue(key, is_shift_pressed); - param->is_down = is_down; - - if (param->key_value == LWE::KeyValue::TVReturnKey && - webview_instance_->CanGoBack()) { - webview_instance_->GoBack(); + if (is_down) { + Evas_Event_Key_Down downEvent; + memset(&downEvent, 0, sizeof(Evas_Event_Key_Down)); + downEvent.key = key; + downEvent.string = string; + void* evasKeyEvent = static_cast(&downEvent); + EwkInternalApiBinding::GetInstance().view.SendKeyEvent( + webview_instance_, evasKeyEvent, is_down); + return true; + } else { + Evas_Event_Key_Up upEvent; + memset(&upEvent, 0, sizeof(Evas_Event_Key_Up)); + upEvent.key = key; + upEvent.string = string; + void* evasKeyEvent = static_cast(&upEvent); + EwkInternalApiBinding::GetInstance().view.SendKeyEvent( + webview_instance_, evasKeyEvent, is_down); return true; } - webview_instance_->AddIdleCallback( - [](void* data) { - Param* param = reinterpret_cast(data); - if (param->is_down) { - param->webview_instance->DispatchKeyDownEvent(param->key_value); - param->webview_instance->DispatchKeyPressEvent(param->key_value); - } else { - param->webview_instance->DispatchKeyUpEvent(param->key_value); - } - delete param; - }, - param); - return false; } +void WebView::Resume() { ewk_view_resume(webview_instance_); } + +void WebView::Stop() { ewk_view_stop(webview_instance_); } + void WebView::SetDirection(int direction) { // TODO: Implement if necessary. } void WebView::InitWebView() { - if (webview_instance_) { - webview_instance_->Destroy(); - webview_instance_ = nullptr; - } - - float pixel_ratio = 1.0; - - auto on_prepare_image = [this]() -> LWE::WebContainer::ExternalImageInfo { - std::lock_guard lock(mutex_); - LWE::WebContainer::ExternalImageInfo result; - if (!working_surface_) { - working_surface_ = tbm_pool_->GetAvailableBuffer(); - } - if (working_surface_) { - result.imageAddress = working_surface_->Surface(); - } else { - result.imageAddress = nullptr; - } - return result; - }; - auto on_flush = [this](LWE::WebContainer* container, bool is_rendered) { - if (is_rendered) { - std::lock_guard lock(mutex_); - if (candidate_surface_) { - tbm_pool_->Release(candidate_surface_); - candidate_surface_ = nullptr; - } - candidate_surface_ = working_surface_; - working_surface_ = nullptr; - texture_registrar_->MarkTextureFrameAvailable(GetTextureId()); - } + char* chromium_argv[] = { + const_cast("--disable-pinch"), + const_cast("--js-flags=--expose-gc"), + const_cast("--single-process"), + const_cast("--no-zygote"), }; - - webview_instance_ = - reinterpret_cast(createWebViewInstance( - 0, 0, width_, height_, pixel_ratio, "SamsungOneUI", "ko-KR", - "Asia/Seoul", on_prepare_image, on_flush, use_sw_backend_)); - -#ifndef TV_PROFILE - LWE::Settings settings = webview_instance_->GetSettings(); - settings.SetUserAgentString( - "Mozilla/5.0 (like Gecko/54.0 Firefox/54.0) Mobile"); - webview_instance_->SetSettings(settings); -#endif + int chromium_argc = sizeof(chromium_argv) / sizeof(chromium_argv[0]); + EwkInternalApiBinding::GetInstance().main.SetArguments(chromium_argc, + chromium_argv); + + ewk_init(); + Ecore_Evas* evas = ecore_evas_new("wayland_egl", 0, 0, 1, 1, 0); + + webview_instance_ = ewk_view_add(ecore_evas_get(evas)); + ecore_evas_focus_set(evas, true); + ewk_view_focus_set(webview_instance_, true); + EwkInternalApiBinding::GetInstance().view.OffscreenRenderingEnabledSet( + webview_instance_, true); + + Ewk_Settings* settings = ewk_view_settings_get(webview_instance_); + + Ewk_Context* context = ewk_view_context_get(webview_instance_); + Ewk_Cookie_Manager* manager = ewk_context_cookie_manager_get(context); + if (manager) { + ewk_cookie_manager_accept_policy_set( + manager, EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY); + } + ewk_settings_viewport_meta_tag_set(settings, false); + EwkInternalApiBinding::GetInstance().settings.ImePanelEnabledSet(settings, + true); + ewk_settings_javascript_enabled_set(settings, true); + + EwkInternalApiBinding::GetInstance().view.ImeWindowSet(webview_instance_, + win_); + EwkInternalApiBinding::GetInstance().view.KeyEventsEnabledSet( + webview_instance_, true); + ewk_context_cache_model_set(context, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER); + + evas_object_smart_callback_add(webview_instance_, "offscreen,frame,rendered", + &WebView::OnFrameRendered, this); + evas_object_smart_callback_add(webview_instance_, "load,started", + &WebView::OnLoadStarted, this); + evas_object_smart_callback_add(webview_instance_, "load,finished", + &WebView::OnLoadFinished, this); + evas_object_smart_callback_add(webview_instance_, "load,error", + &WebView::OnLoadError, this); + evas_object_smart_callback_add(webview_instance_, "console,message", + &WebView::OnConsoleMessage, this); + evas_object_smart_callback_add(webview_instance_, "policy,navigation,decide", + &WebView::OnNavigationPolicy, this); + Resize(width_, height_); + evas_object_show(webview_instance_); + + evas_object_data_set(webview_instance_, kEwkInstance, this); } -void WebView::HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { +void WebView::HandleMethodCall(const FlMethodCall& method_call, + std::unique_ptr result) { if (!webview_instance_) { result->Error("Invalid operation", "The webview instance has not been initialized."); @@ -696,12 +387,10 @@ void WebView::HandleMethodCall( const std::string& method_name = method_call.method_name(); const flutter::EncodableValue* arguments = method_call.arguments(); - LOG_DEBUG("Handle a method call: %s", method_name.c_str()); - if (method_name == "loadUrl") { std::string url; if (GetValueFromEncodableMap(arguments, "url", &url)) { - webview_instance_->LoadURL(url); + ewk_view_url_set(webview_instance_, url.c_str()); result->Success(); } else { result->Error("Invalid argument", "No url provided."); @@ -713,39 +402,31 @@ void WebView::HandleMethodCall( } result->Success(); } else if (method_name == "canGoBack") { - result->Success(flutter::EncodableValue(webview_instance_->CanGoBack())); + result->Success( + flutter::EncodableValue(ewk_view_back_possible(webview_instance_))); } else if (method_name == "canGoForward") { - result->Success(flutter::EncodableValue(webview_instance_->CanGoForward())); + result->Success( + flutter::EncodableValue(ewk_view_forward_possible(webview_instance_))); } else if (method_name == "goBack") { - webview_instance_->GoBack(); + ewk_view_back(webview_instance_); result->Success(); } else if (method_name == "goForward") { - webview_instance_->GoForward(); + ewk_view_forward(webview_instance_); result->Success(); } else if (method_name == "reload") { - webview_instance_->Reload(); + ewk_view_reload(webview_instance_); result->Success(); } else if (method_name == "currentUrl") { - result->Success(flutter::EncodableValue(webview_instance_->GetURL())); + result->Success( + flutter::EncodableValue(ewk_view_url_get(webview_instance_))); } else if (method_name == "evaluateJavascript" || method_name == "runJavascriptReturningResult" || method_name == "runJavascript") { const auto* javascript = std::get_if(arguments); if (javascript) { - bool should_return = method_name != "runJavascript"; - auto on_result = [result = result.release(), - should_return](std::string value) { - LOG_DEBUG("JavaScript evaluation result: %s", value.c_str()); - if (result) { - if (should_return) { - result->Success(flutter::EncodableValue(value)); - } else { - result->Success(); - } - delete result; - } - }; - webview_instance_->EvaluateJavaScript(*javascript, on_result); + auto p_result = result.release(); + ewk_view_script_execute(webview_instance_, javascript->c_str(), + &WebView::OnEvaluateJavaScript, p_result); } else { result->Error("Invalid argument", "The argument must be a string."); } @@ -760,26 +441,17 @@ void WebView::HandleMethodCall( } result->Success(); } else if (method_name == "removeJavascriptChannels") { - const auto* channels = std::get_if(arguments); - if (channels) { - for (flutter::EncodableValue channel : *channels) { - if (std::holds_alternative(channel)) { - webview_instance_->RemoveJavascriptInterface( - std::get(channel), "postMessage"); - } - } - } - result->Success(); + result->NotImplemented(); } else if (method_name == "clearCache") { - webview_instance_->ClearCache(); - result->Success(); + result->NotImplemented(); } else if (method_name == "getTitle") { - result->Success(flutter::EncodableValue(webview_instance_->GetTitle())); + result->Success(flutter::EncodableValue( + std::string(ewk_view_title_get(webview_instance_)))); } else if (method_name == "scrollTo") { int x = 0, y = 0; if (GetValueFromEncodableMap(arguments, "x", &x) && GetValueFromEncodableMap(arguments, "y", &y)) { - webview_instance_->ScrollTo(x, y); + ewk_view_scroll_set(webview_instance_, x, y); result->Success(); } else { result->Error("Invalid argument", "No x or y provided."); @@ -788,15 +460,19 @@ void WebView::HandleMethodCall( int x = 0, y = 0; if (GetValueFromEncodableMap(arguments, "x", &x) && GetValueFromEncodableMap(arguments, "y", &y)) { - webview_instance_->ScrollBy(x, y); + ewk_view_scroll_by(webview_instance_, x, y); result->Success(); } else { result->Error("Invalid argument", "No x or y provided."); } } else if (method_name == "getScrollX") { - result->Success(flutter::EncodableValue(webview_instance_->GetScrollX())); + int x = 0; + ewk_view_scroll_pos_get(webview_instance_, &x, nullptr); + result->Success(flutter::EncodableValue(x)); } else if (method_name == "getScrollY") { - result->Success(flutter::EncodableValue(webview_instance_->GetScrollY())); + int y = 0; + ewk_view_scroll_pos_get(webview_instance_, nullptr, &y); + result->Success(flutter::EncodableValue(y)); } else if (method_name == "loadFlutterAsset") { const auto* key = std::get_if(arguments); if (key) { @@ -805,7 +481,7 @@ void WebView::HandleMethodCall( std::string url = std::string("file://") + res_path + "flutter_assets/" + *key; free(res_path); - webview_instance_->LoadURL(url); + ewk_view_url_set(webview_instance_, url.c_str()); result->Success(); } else { result->Error("Operation failed", @@ -823,13 +499,14 @@ void WebView::HandleMethodCall( if (GetValueFromEncodableMap(arguments, "baseUrl", &base_url)) { LOG_WARN("loadHtmlString: baseUrl is not supported and will be ignored."); } - webview_instance_->LoadData(html); + ewk_view_html_string_load(webview_instance_, html.c_str(), base_url.c_str(), + nullptr); result->Success(); } else if (method_name == "loadFile") { const auto* file_path = std::get_if(arguments); if (file_path) { std::string url = std::string("file://") + *file_path; - webview_instance_->LoadURL(url); + ewk_view_url_set(webview_instance_, url.c_str()); result->Success(); } else { result->Error("Invalid argument", "The argument must be a string."); @@ -843,9 +520,8 @@ void WebView::HandleMethodCall( } } -void WebView::HandleCookieMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { +void WebView::HandleCookieMethodCall(const FlMethodCall& method_call, + std::unique_ptr result) { if (!webview_instance_) { result->Error("Invalid operation", "The webview instance has not been initialized."); @@ -855,9 +531,14 @@ void WebView::HandleCookieMethodCall( const std::string& method_name = method_call.method_name(); if (method_name == "clearCookies") { - LWE::CookieManager* cookie = LWE::CookieManager::GetInstance(); - cookie->ClearCookies(); - result->Success(flutter::EncodableValue(true)); + Ewk_Cookie_Manager* manager = + ewk_context_cookie_manager_get(ewk_view_context_get(webview_instance_)); + if (manager) { + ewk_cookie_manager_cookies_clear(manager); + result->Success(flutter::EncodableValue(true)); + } else { + result->Error("Operation failed", "Failed to get cookie manager"); + } } else { result->NotImplemented(); } @@ -879,3 +560,125 @@ FlutterDesktopGpuSurfaceDescriptor* WebView::ObtainGpuSurface(size_t width, candidate_surface_ = nullptr; return rendered_surface_->GpuSurface(); } + +void WebView::OnFrameRendered(void* data, Evas_Object* obj, void* event_info) { + if (event_info) { + WebView* webview = static_cast(data); + + std::lock_guard lock(webview->mutex_); + if (!webview->working_surface_) { + webview->working_surface_ = webview->tbm_pool_->GetAvailableBuffer(); + webview->working_surface_->UseExternalBuffer(); + } + webview->working_surface_->SetExternalBuffer( + static_cast(event_info)); + + if (webview->candidate_surface_) { + webview->tbm_pool_->Release(webview->candidate_surface_); + webview->candidate_surface_ = nullptr; + } + webview->candidate_surface_ = webview->working_surface_; + webview->working_surface_ = nullptr; + webview->texture_registrar_->MarkTextureFrameAvailable( + webview->GetTextureId()); + } +} + +void WebView::OnLoadStarted(void* data, Evas_Object* obj, void* event_info) { + WebView* webview = static_cast(data); + std::string url = std::string(ewk_view_url_get(webview->webview_instance_)); + flutter::EncodableMap args; + args.insert(std::make_pair( + flutter::EncodableValue("url"), flutter::EncodableValue(url))); + webview->channel_->InvokeMethod( + "onPageStarted", std::make_unique(args)); +} + +void WebView::OnLoadFinished(void* data, Evas_Object* obj, void* event_info) { + WebView* webview = static_cast(data); + std::string url = std::string(ewk_view_url_get(webview->webview_instance_)); + flutter::EncodableMap args; + args.insert(std::make_pair( + flutter::EncodableValue("url"), flutter::EncodableValue(url))); + webview->channel_->InvokeMethod( + "onPageFinished", std::make_unique(args)); +} + +void WebView::OnLoadError(void* data, Evas_Object* obj, void* event_info) { + WebView* webview = static_cast(data); + Ewk_Error* error = static_cast(event_info); + flutter::EncodableMap args = { + {flutter::EncodableValue("errorCode"), + flutter::EncodableValue(ewk_error_code_get(error))}, + {flutter::EncodableValue("description"), + flutter::EncodableValue(ewk_error_description_get(error))}, + {flutter::EncodableValue("errorType"), + flutter::EncodableValue(ErrorCodeToString(ewk_error_code_get(error)))}, + {flutter::EncodableValue("failingUrl"), + flutter::EncodableValue(ewk_error_url_get(error))}, + }; + webview->channel_->InvokeMethod( + "onWebResourceError", std::make_unique(args)); +} + +void WebView::OnConsoleMessage(void* data, Evas_Object* obj, void* event_info) { + Ewk_Console_Message* message = static_cast(event_info); + LOG_INFO( + "console message:%s: %d: %d: %s", + EwkInternalApiBinding::GetInstance().console_message.SourceGet(message), + EwkInternalApiBinding::GetInstance().console_message.LineGet(message), + EwkInternalApiBinding::GetInstance().console_message.LevelGet(message), + EwkInternalApiBinding::GetInstance().console_message.TextGet(message)); +} + +void WebView::OnNavigationPolicy(void* data, Evas_Object* obj, + void* event_info) { + WebView* webview = static_cast(data); + Ewk_Policy_Decision* policy_decision = + static_cast(event_info); + + const char* url = ewk_policy_decision_url_get(policy_decision); + if (!webview->has_navigation_delegate_) { + ewk_policy_decision_use(policy_decision); + return; + } + ewk_view_suspend(webview->webview_instance_); + flutter::EncodableMap args = { + {flutter::EncodableValue("url"), flutter::EncodableValue(url)}, + {flutter::EncodableValue("isForMainFrame"), + flutter::EncodableValue(true)}, + }; + auto result = std::make_unique(webview); + webview->channel_->InvokeMethod( + "navigationRequest", std::make_unique(args), + std::move(result)); +} + +void WebView::OnEvaluateJavaScript(Evas_Object* obj, const char* result_value, + void* user_data) { + FlMethodResult* result = static_cast(user_data); + result->Success(flutter::EncodableValue(result_value)); + delete result; +} + +void WebView::OnJavaScriptMessage(Evas_Object* obj, + Ewk_Script_Message message) { + if (obj) { + WebView* webview = + static_cast(evas_object_data_get(obj, kEwkInstance)); + if (webview->channel_) { + std::string channel_name(message.name); + std::string channel_message(static_cast(message.body)); + + flutter::EncodableMap args = { + {flutter::EncodableValue("channel"), + flutter::EncodableValue(channel_name)}, + {flutter::EncodableValue("message"), + flutter::EncodableValue(channel_message)}, + }; + webview->channel_->InvokeMethod( + "javascriptChannelMessage", + std::make_unique(args)); + } + } +} diff --git a/packages/webview_flutter/tizen/src/webview.h b/packages/webview_flutter/tizen/src/webview.h index f8f8b21e9..a0a528a6a 100644 --- a/packages/webview_flutter/tizen/src/webview.h +++ b/packages/webview_flutter/tizen/src/webview.h @@ -5,6 +5,8 @@ #ifndef FLUTTER_PLUGIN_WEBVIEW_H_ #define FLUTTER_PLUGIN_WEBVIEW_H_ +#include +#include #include #include #include @@ -17,10 +19,6 @@ #include #include -namespace LWE { -class WebContainer; -} - class BufferPool; class BufferUnit; @@ -28,7 +26,7 @@ class WebView : public PlatformView { public: WebView(flutter::PluginRegistrar* registrar, int view_id, flutter::TextureRegistrar* texture_registrar, double width, - double height, const flutter::EncodableValue& params); + double height, const flutter::EncodableValue& params, void* win); ~WebView(); virtual void Dispose() override; @@ -44,7 +42,11 @@ class WebView : public PlatformView { uint32_t modifiers, uint32_t scan_code, bool is_down) override; - LWE::WebContainer* GetWebViewInstance() { return webview_instance_; } + void Resume(); + + void Stop(); + + Evas_Object* GetWebViewInstance() { return webview_instance_; } FlutterDesktopGpuSurfaceDescriptor* ObtainGpuSurface(size_t width, size_t height); @@ -63,21 +65,31 @@ class WebView : public PlatformView { void InitWebView(); - LWE::WebContainer* webview_instance_ = nullptr; + static void OnFrameRendered(void* data, Evas_Object* obj, void* event_info); + static void OnLoadStarted(void* data, Evas_Object* obj, void* event_info); + static void OnLoadFinished(void* data, Evas_Object* obj, void* event_info); + static void OnLoadError(void* data, Evas_Object* obj, void* event_info); + static void OnConsoleMessage(void* data, Evas_Object* obj, void* event_info); + static void OnNavigationPolicy(void* data, Evas_Object* obj, + void* event_info); + static void OnEvaluateJavaScript(Evas_Object* obj, const char* result_value, + void* user_data); + static void OnJavaScriptMessage(Evas_Object* obj, Ewk_Script_Message message); + + Evas_Object* webview_instance_ = nullptr; + void* win_ = nullptr; flutter::TextureRegistrar* texture_registrar_; - double width_; - double height_; + double width_ = 0.0; + double height_ = 0.0; BufferUnit* working_surface_ = nullptr; BufferUnit* candidate_surface_ = nullptr; BufferUnit* rendered_surface_ = nullptr; - bool is_mouse_lbutton_down_ = false; bool has_navigation_delegate_ = false; bool has_progress_tracking_ = false; std::unique_ptr> channel_; std::unique_ptr texture_variant_; std::mutex mutex_; std::unique_ptr tbm_pool_; - bool use_sw_backend_; }; #endif // FLUTTER_PLUGIN_WEBVIEW_H_ diff --git a/packages/webview_flutter/tizen/src/webview_factory.cc b/packages/webview_flutter/tizen/src/webview_factory.cc index a7344d9aa..13fbec833 100644 --- a/packages/webview_flutter/tizen/src/webview_factory.cc +++ b/packages/webview_flutter/tizen/src/webview_factory.cc @@ -12,36 +12,17 @@ #include #include "log.h" -#include "lwe/LWEWebView.h" #include "webview.h" -static std::string GetAppDataPath() { - char* path = app_get_data_path(); - if (!path) { - return "/tmp/"; - } - std::string result = std::string(path); - free(path); - return result; -} - -WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar) - : PlatformViewFactory(registrar) { +WebViewFactory::WebViewFactory(flutter::PluginRegistrar* registrar, void* win) + : PlatformViewFactory(registrar), win_(win) { texture_registrar_ = registrar->texture_registrar(); - - std::string data_path = GetAppDataPath(); - std::string local_storage_path = data_path + "StarFish_localStorage.db"; - std::string cookie_path = data_path + "StarFish_cookies.db"; - std::string cache_path = data_path + "Starfish_cache.db"; - - LWE::LWE::Initialize(local_storage_path.c_str(), cookie_path.c_str(), - cache_path.c_str()); } PlatformView* WebViewFactory::Create(int view_id, double width, double height, const ByteMessage& params) { return new WebView(GetPluginRegistrar(), view_id, texture_registrar_, width, - height, *GetCodec().DecodeMessage(params)); + height, *GetCodec().DecodeMessage(params), win_); } -void WebViewFactory::Dispose() { LWE::LWE::Finalize(); } +void WebViewFactory::Dispose() {} diff --git a/packages/webview_flutter/tizen/src/webview_factory.h b/packages/webview_flutter/tizen/src/webview_factory.h index 0332b03dc..ebb7c96d2 100644 --- a/packages/webview_flutter/tizen/src/webview_factory.h +++ b/packages/webview_flutter/tizen/src/webview_factory.h @@ -13,7 +13,7 @@ class WebViewFactory : public PlatformViewFactory { public: - WebViewFactory(flutter::PluginRegistrar* registrar); + WebViewFactory(flutter::PluginRegistrar* registrar, void* win); virtual PlatformView* Create(int view_id, double width, double height, const ByteMessage& params) override; @@ -22,6 +22,7 @@ class WebViewFactory : public PlatformViewFactory { private: flutter::TextureRegistrar* texture_registrar_; + void* win_ = nullptr; }; #endif // FLUTTER_PLUGIN_WEBVIEW_FACTORY_H_ diff --git a/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc b/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc index 66b6fd6e3..749f51a9a 100644 --- a/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc +++ b/packages/webview_flutter/tizen/src/webview_flutter_tizen_plugin.cc @@ -34,7 +34,11 @@ void WebviewFlutterTizenPluginRegisterWithRegistrar( flutter::PluginRegistrar* registrar = flutter::PluginRegistrarManager::GetInstance() ->GetRegistrar(core_registrar); + FlutterDesktopViewRef view = + FlutterDesktopPluginRegistrarGetView(core_registrar); FlutterDesktopRegisterViewFactory( - core_registrar, kViewType, std::make_unique(registrar)); + core_registrar, kViewType, + std::make_unique( + registrar, FlutterDesktopViewGetNativeHandle(view))); WebviewFlutterTizenPlugin::RegisterWithRegistrar(registrar); }