flutter-tizen / plugins

Flutter plugins for Tizen
64 stars 46 forks source link

[webview_flutter] Introduce webview_flutter base on chromium engine(ewk) #399

Closed bwikbs closed 1 year ago

bwikbs commented 2 years ago

previous work: https://github.com/flutter-tizen/plugins/pull/145 new requirements: https://github.com/flutter-tizen/plugins/issues/390


Recently, I consider to re-introduce ewk webview for new requirements. Most of the plug-in code(dart+native) is the same with lwe version, but it is planned to be a separate package. (Unfortunately, emulator is not supported)

JRazek commented 2 years ago

Hi, there's a problem with building the plugin. When building an /example from https://github.com/bwikbs/plugins/tree/ewk_webview_flutter with a flutter-tizen build tpk -ptv I receive the following error:

"/home/user/tizen-studio/tools/smart-build-interface/../llvm-10/bin/clang++" -c "src/webview.cc" -o "Release/src/webview.o" -DTIZEN_DEPRECATION -DDEPRECATION_WARNING -DTV_PROFILE -DFLUTTER_PLUGIN_IMPL -Iinc -Isrc  -I"pch" -O3 -Wall -c
-fmessage-length=0 -std=c++14 -target arm-tizen-linux-gnueabi -gcc-toolchain "/home/user/tizen-studio/tools/smart-build-interface/../arm-linux-gnueabi-gcc-9.2/" -ccc-gcc-name arm-linux-gnueabi-g++ -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
-mtune=cortex-a8 -Wno-gnu -fstack-protector-strong -Wno-unused-command-line-argument -fdebug-default-version=3 -std=c++17 -fPIE --sysroot="/home/user/tizen-studio/platforms/tizen-5.5/wearable/rootstraps/wearable-5.5-device.core"
-Werror-implicit-function-declaration  -fPIC -I"/home/user/sources/flutter-tizen/flutter/bin/cache/artifacts/engine/tizen-common/cpp_client_wrapper/include" -I"/home/user/sources/flutter-tizen/flutter/bin/cache/artifacts/engine/tizen-common/public"
-Wp,@./Release/objs/platform_incs_file.inc
In file included from src/webview.cc:5:
src/webview.h:45:37: error: unknown type name 'Ecore_Event_Key'; did you mean 'Ecore_Event'?
  virtual void DispatchKeyDownEvent(Ecore_Event_Key* key) override;
                                    ^~~~~~~~~~~~~~~
                                    Ecore_Event
/home/user/tizen-studio/platforms/tizen-5.5/wearable/rootstraps/wearable-5.5-device.core/usr/include/ecore-1/Ecore_Common.h:591:45: note: 'Ecore_Event' declared here
typedef struct _Ecore_Event                 Ecore_Event;    /**< A handle for an event */
                                            ^
In file included from src/webview.cc:5:
src/webview.h:45:16: error: 'DispatchKeyDownEvent' marked 'override' but does not override any member functions
  virtual void DispatchKeyDownEvent(Ecore_Event_Key* key) override;
               ^
src/webview.h:46:35: error: unknown type name 'Ecore_Event_Key'; did you mean 'Ecore_Event'?
  virtual void DispatchKeyUpEvent(Ecore_Event_Key* key) override;
                                  ^~~~~~~~~~~~~~~
                                  Ecore_Event
/home/user/tizen-studio/platforms/tizen-5.5/wearable/rootstraps/wearable-5.5-device.core/usr/include/ecore-1/Ecore_Common.h:591:45: note: 'Ecore_Event' declared here
typedef struct _Ecore_Event                 Ecore_Event;    /**< A handle for an event */
                                            ^
In file included from src/webview.cc:5:
src/webview.h:46:16: error: 'DispatchKeyUpEvent' marked 'override' but does not override any member functions
  virtual void DispatchKeyUpEvent(Ecore_Event_Key* key) override;
               ^
src/webview.cc:271:36: error: use of undeclared identifier 'Ecore_Event_Key'; did you mean 'ecore_event_del'?
void WebView::DispatchKeyDownEvent(Ecore_Event_Key* key_event) {
                                   ^~~~~~~~~~~~~~~
                                   ecore_event_del
/home/user/tizen-studio/platforms/tizen-5.5/wearable/rootstraps/wearable-5.5-device.core/usr/include/ecore-1/Ecore_Common.h:765:12: note: 'ecore_event_del' declared here
EAPI void *ecore_event_del(Ecore_Event *event);
           ^
src/webview.cc:271:15: error: variable has incomplete type 'void'
void WebView::DispatchKeyDownEvent(Ecore_Event_Key* key_event) {
              ^
src/webview.cc:271:53: error: use of undeclared identifier 'key_event'
void WebView::DispatchKeyDownEvent(Ecore_Event_Key* key_event) {
                                                    ^
src/webview.cc:271:63: error: expected ';' after top level declarator
void WebView::DispatchKeyDownEvent(Ecore_Event_Key* key_event) {
                                                              ^
bbrto21 commented 2 years ago

@JRazek Hi flutter_platform_view.h of the engine has recently been updated. Please try using the latest version of flutter-tizen.

bwikbs commented 2 years ago

No, This PR is not include platform_view's change. You should use previous one.(https://github.com/flutter-tizen/flutter-tizen/commit/ad7da6b0ae8e88343bf94869c1ef0875bfeb2cbe) OR Wait for the updating.(May be tomorrow?)

JRazek commented 2 years ago

No, This PR is not include platform_view's change. You should use previous one.(flutter-tizen/flutter-tizen@ad7da6b) OR Wait for the updating.(May be tomorrow?)

@bwikbs you sent a link to a commit with a docs change. Could you please send a link to a very commit that you're positive of being able to compile?

JRazek commented 2 years ago

@JRazek Hi flutter_platform_view.h of the engine has recently been updated. Please try using the latest version of flutter-tizen.

I'm running the latest version cloned from https://github.com/flutter-tizen/flutter-tizen

bwikbs commented 2 years ago

@JRazek

@bwikbs you sent a link to a commit with a docs change. Could you please send a link to a very commit that you're positive of being able to compile?

Engine will be changed in the next commit, so just use that commit. I have already confirmed with that commit. And.. if there's something wrong with this task, let me know right away.

bwikbs commented 2 years ago

@JRazek Now, you can use ewk_webview with latest flutter-tizen. Here is my test result.


dump_screen

root:~> cat /etc/tizen-release 
Tizen7/Unified 7.0.0 (arm)
VERSION = 7.0.0
CODENAME = TSDF
BUILD_ID=tizen-unified_20220502.3_tizen-headed-armv7l
JRazek commented 2 years ago

Thanks, the updates solve the compilation error for me.

bwikbs commented 2 years ago

@JRazek navigationDelegate has been temporarily implemented. Please test it and let me know the results.

JRazek commented 2 years ago

@bwikbs Webview now seems to be quite unstable. After launching webview all the screen started blinking randomly, very often it resulted in a page that was impossible to interact with. And after 3 attempts of reloading plugin, the app crashed. The navigationDelegate callback in flutter was called though...

bwikbs commented 2 years ago

Can you share sample code?

JRazek commented 2 years ago

sure, I'm using a following widget for testing:


class GoogleLoginPage extends StatelessWidget {
  const GoogleLoginPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WebView(
      onWebViewCreated: (controller) async {
        final cookieManager = CookieManager();
        await cookieManager.clearCookies();
      },
      initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
      initialUrl:
          'https://accounts.google.com/o/oauth2/auth?response_type=token&client_id=448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&redirect_uri=http%3A%2F%2F127.0.0.1%3A33467',
      javascriptMode: JavascriptMode.unrestricted,
      userAgent: 'Chrome/81.0.0.0 Mobile',
      onPageStarted: (data) {
        print("");
      },
      navigationDelegate: (data) {
        print('navigated to:' + data.url);
        return NavigationDecision.navigate;
      },
    );
  }
}
bwikbs commented 2 years ago

I attached the your sample code to the webview example and tested it simply. The following urls were loaded sequentially, and the symptoms you mentioned were not observed. (It stayed stable on the about:blank page.) Can you share the full code you tested? And I want to know in what environment it was tested.


url1:

https://accounts.google.com/o/oauth2/auth?response_type=token&client_id=448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&redirect_uri=http%3A%2F%2F127.0.0.1%3A33467


url2: https://accounts.google.com/AccountChooser?oauth=1&continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Flegacy%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAOAvCKLkwu9SWK1PCya75mOIEKjD_Fr_fjvrjfGR-Ba9rGcYpGQw84AgyymWVwHeitg18tIJFZOpz7v-nboErkj2eRNYlxbhV_F92XW9d23l9E6kRHH-vQkFaika_f7pyOBKKD3mSxhiMaBzC_FMOb2xEfrp87qyE26DVo_1kR4BJSxM-byPlgxKCyYRSVIb7ZilgBVg4Ci3zcQYbwJC8lBBn_ggnZweRfuW886HCDCBzX0Qzpnc629btZGLXjzInLxUV9MFcQVS3GIm2EpAodJv6l55OTQvdCIA0FbjNAzLC7uWSpraKdhpTWoztlUyORYUttBcpVBp48vuF0Yj3LlM9vkQFIUcTJgWJRbrmD1wS4TaHtuLFHHqXL3lyAK4zZRbb2w-WBkg-R9OiwMl6Qs78HHC5g-wJ52nRp5YMhxSJavKJE2En2O4iEZ_qo4s5jGc0toF3j3jUMVa78pJiNouxCacw%26as%3DS1896276591%253A1656316589790539%26client_id%3D448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com%23


url3: https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Faccounts.google.com%2Fsignin%2Foauth%2Flegacy%2Fconsent%3Fauthuser%3Dunknown%26part%3DAJi8hAOAvCKLkwu9SWK1PCya75mOIEKjD_Fr_fjvrjfGR-Ba9rGcYpGQw84AgyymWVwHeitg18tIJFZOpz7v-nboErkj2eRNYlxbhV_F92XW9d23l9E6kRHH-vQkFaika_f7pyOBKKD3mSxhiMaBzC_FMOb2xEfrp87qyE26DVo_1kR4BJSxM-byPlgxKCyYRSVIb7ZilgBVg4Ci3zcQYbwJC8lBBn_ggnZweRfuW886HCDCBzX0Qzpnc629btZGLXjzInLxUV9MFcQVS3GIm2EpAodJv6l55OTQvdCIA0FbjNAzLC7uWSpraKdhpTWoztlUyORYUttBcpVBp48vuF0Yj3LlM9vkQFIUcTJgWJRbrmD1wS4TaHtuLFHHqXL3lyAK4zZRbb2w-WBkg-R9OiwMl6Qs78HHC5g-wJ52nRp5YMhxSJavKJE2En2O4iEZ_qo4s5jGc0toF3j3jUMVa78pJiNouxCacw%26as%3DS1896276591%253A1656316589790539%26client_id%3D448618578101-sg12d2qin42cpr00f8b0gehs5s7inm0v.apps.googleusercontent.com%23&sacu=1&oauth=1&rip=1


url4: about:blank

JRazek commented 2 years ago

I see now. The blinks are probably just redirects. I do not understand why the user is redirected to about:blank though.

If I get it correctly, the null navigationDelegate should allow all the flow. Same should go for the

(data){
    return NavigationDecision.navigate;
}

It is also worth mentioning that after reload it happens to crash with

[  +13 ms] [E] globalapps/org.tizen.firebase_desktop_example/bin/Runner.dll: pthread_mutex_lock.c:81: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
[        ] [E] onSigabrt called
bwikbs commented 2 years ago

@JRazek I've update code. Plz, Try again & let me know result.

[  +13 ms] [E] globalapps/org.tizen.firebase_desktop_example/bin/Runner.dll: pthread_mutex_lock.c:81: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
[        ] [E] onSigabrt called

How can I reproduce this issue?

JRazek commented 2 years ago

@bwikbs I receive following error on an attempt to close the Webview in a stateful widget.

[+12272 ms] [E] terminate called after throwing an instance of 'std::logic_error'
[        ]   what():  basic_string::_M_construct null not valid

Scenario is following: I've created a stateful widget that has a button. On pressed event of the button's state, the webview is shown instead of the button page.

Once the webview has done it's job the state of widget is changed back to the initial state, which forces the webview to close. In that moment the app crashes with the error I've pasted.

bwikbs commented 2 years ago

@JRazek Please share some sample code so I can test it.

JRazek commented 2 years ago

@bwikbs This app crashes the code when the user tries to navigate to https://www.youtube.com,

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(const MaterialApp(home: AppExample()));

class AppExample extends StatefulWidget {
  const AppExample({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return WebviewState();
  }
}

class WebviewExample extends StatelessWidget {
  const WebviewExample(this.callback, {Key? key}) : super(key: key);
  final Function callback;
  @override
  WebView build(BuildContext context) {
    return WebView(
      onWebViewCreated: (controller) async {},
      initialUrl: 'https://google.com',
      javascriptMode: JavascriptMode.unrestricted,
      navigationDelegate: (data) {
        print('navigated to: ${data.url}');
        if (data.url.startsWith('https://www.youtube.com')) {
          callback();
          return NavigationDecision.prevent;
        }
        return NavigationDecision.navigate;
      },
    );
  }
}

class WebviewState extends State {
  bool webviewOn = true;
  @override
  Widget build(BuildContext context) {
    return webviewOn
        ? WebviewExample(() {
            setState(() {
              webviewOn = false;
            });
          })
        : const Scaffold();
  }
}
bwikbs commented 2 years ago

@JRazek I've tested your sample with only modifing initlaUrl like this:

      onWebViewCreated: (controller) async {},
      initialUrl: 'https://www.youtube.com',
      javascriptMode: JavascriptMode.unrestricted,

I can't find any crash on my rpi4. Is there any condition to produce this issue?

JRazek commented 2 years ago

@JRazek I've tested your sample with only modifing initlaUrl like this:

      onWebViewCreated: (controller) async {},
      initialUrl: 'https://www.youtube.com',
      javascriptMode: JavascriptMode.unrestricted,

I can't find any crash on my rpi4. Is there any condition to produce this issue?

@bwikbs Yes, please just use the app as I've shown and allow navigationDelegate to handle the youtube call. Otherwise preserve the original functionality such that after a few redirects, you change the WebviewState::webviewOn from true to false.

It is also worth mentioning that I use the app from TV 6.5 emulator

bwikbs commented 2 years ago

@JRazek Now, I can reproduce this issue.

bwikbs commented 2 years ago

@JRazek ewk's current APIs doesn't match what we want for navigationDelegate. So I used a little trick, and this doesn't seem to work well for redirected urls. Looks like I'll have to discuss this with the ewk team. This will take some time... Is this urgent for your task? Is it possible to bypass this part and proceed task? How about consider using a new plugin(https://github.com/flutter-tizen/plugins/pull/413)?


+) Now I think the problem you mentioned is solved. Still, I'd love to hear your thoughts on using the new plugin.

bbrto21 commented 1 year ago

I am reviewing existing implementations to take over this task.

bbrto21 commented 1 year ago

I think we need to publish new plugin to webview_flutter similar to https://github.com/flutter-tizen/plugins/pull/400. And end-user should select as follows.

  webview_flutter: ^3.0.4
  webview_flutter_tizen: ^0.5.6 
  # or
  # webview_flutter_lwe: ^0.1.0

webview_flutter_tizen will use ewk webview. Because ewk webview is official Tizen's Native Webview. some internal APIs are used, but they will all be imported dynamically. Therefore, the current implementation using lwe makes sense to have a new name as webview_flutter_lwe. (Having a prebuilt so means that this so is a kind of external library)

In addition, webview uses a platform view which name as TizenView. This is part of the current implementation, but it actually had to be part of the flutter framework. But we can't, so I'm going to cut this out with a new plugin which name as platform_view_tizen. And I'm going to add dependency on this to both.

If you don't have a better idea for my plan, I will proceed as it is.

bbrto21 commented 1 year ago

In addition, webview uses a platform view which name as TizenView. This is part of the current implementation, but it actually had to be part of the flutter framework. But we can't, so I'm going to cut this out with a new plugin which name as platform_view_tizen. And I'm going to add dependency on this to both.

@swift-kim It would be great if you could give us a solution on tool side like below, just like we talked offline instead of adding new plugin.

in user implementation files

import 'package:flutter_tizen/widgets.dart';
// ...
@override
Widget build({required BuildContext context}) {
    return TizenView(viewType: 'plugins.flutter.io/webview');
}
// ...

in flutter-tizen ./flutter-tizen/packages/flutter_tizen/lib/widgets.dart

library widgets;
// ...
export 'src/widgets/platform_view.dart'; // Tizen implementation of the platform view
// ...
swift-kim commented 1 year ago

Can we close this issue now?

swift-kim commented 1 year ago

https://github.com/flutter-tizen/plugins/issues/399#issuecomment-1190925023

Does the EWK plugin support YouTube video playback now? I tried to run this YouTube plugin example on several devices (mobile emulator and TV emulator) by adding a dependency on the EWK plugin but failed.