Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Move native implementations to their own packages in preparation for federated architecture #4315

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4a02fd5
Move webview_flutter to webview_flutter/webview_flutter
mvanbeusekom Jul 12, 2021
85825ad
Fixed reference to analysis_options_legacy.yaml
mvanbeusekom Jul 12, 2021
a40bb8d
Initial setup of platform_interface package
mvanbeusekom Jul 20, 2021
81e6b23
Move Android implementation into separate package
mvanbeusekom Aug 2, 2021
ca89f77
Moved iOS implementation to separate package
mvanbeusekom Aug 26, 2021
3b1668a
Update podspec file
mvanbeusekom Aug 26, 2021
580f75a
Extract Javascript channel types
mvanbeusekom Aug 31, 2021
192aa5a
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
55720c9
Added example folder without implementation
mvanbeusekom Sep 1, 2021
108ad7c
Update to use JavascriptChannelRegistry
mvanbeusekom Sep 1, 2021
883a137
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
c17f23a
Export utils
mvanbeusekom Sep 1, 2021
4909624
Export utils
mvanbeusekom Sep 1, 2021
f841e10
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
a35af36
Add JavascriptChannelRegistry to WebViewPlatform
mvanbeusekom Sep 1, 2021
a3c5bb7
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
1c75aa7
Make JavascriptChannelRegistry methods public
mvanbeusekom Sep 1, 2021
c779d31
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
26ff26f
Export JavascriptChannel class
mvanbeusekom Sep 1, 2021
82ed183
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
40e0734
WIP
BeMacized Sep 1, 2021
cca3b48
WIP
BeMacized Sep 1, 2021
4fd9408
Added additional unit-tests
mvanbeusekom Sep 1, 2021
baccaf3
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 1, 2021
b4ecde2
Fix android build
BeMacized Sep 2, 2021
a512034
WIP
BeMacized Sep 1, 2021
65e2458
WIP
BeMacized Sep 1, 2021
bd5856e
Fix android build
BeMacized Sep 2, 2021
722a004
Merge remote-tracking branch 'origin/webview/federated_architecture_p…
BeMacized Sep 2, 2021
5af03f8
Merge branch 'webview/federated_architecture_part_3_wip' into webview…
BeMacized Sep 2, 2021
155c6ee
Added iOS example
BeMacized Sep 2, 2021
02e130b
Fix formatting
mvanbeusekom Sep 2, 2021
c3e2fdd
Merged with master
mvanbeusekom Sep 2, 2021
47046fd
Merge remote-tracking branch 'origin/webview/federated_architecture_p…
mvanbeusekom Sep 3, 2021
529c945
Format
BeMacized Sep 6, 2021
6a7c4c3
Added missing implements key in pubspecs
BeMacized Sep 6, 2021
f1b6b0c
Fix analysis issues
BeMacized Sep 6, 2021
095feae
Format
BeMacized Sep 6, 2021
0bfc585
Add missing license headers
BeMacized Sep 6, 2021
448403b
Add missing LICENSE files
BeMacized Sep 6, 2021
dfca41e
Added missing newlines for license files
BeMacized Sep 6, 2021
433786c
Merge remote-tracking branch 'upstream/master' into webview/federated…
mvanbeusekom Sep 8, 2021
8f5c24a
Merge branch 'webview/federated_architecture_part_2' into webview/fed…
mvanbeusekom Sep 8, 2021
36a2439
Merge branch 'webview/federated_architecture_part_3' of github.com:Ba…
mvanbeusekom Sep 8, 2021
46d2793
Fix bug in showing toaster
mvanbeusekom Sep 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/webview_flutter/analysis_options.yaml

This file was deleted.

94 changes: 0 additions & 94 deletions packages/webview_flutter/webview_flutter/README.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: ../../../analysis_options_legacy.yaml
3 changes: 3 additions & 0 deletions packages/webview_flutter/webview_flutter_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

* Initial release.
25 changes: 25 additions & 0 deletions packages/webview_flutter/webview_flutter_android/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright 2013 The Flutter Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11 changes: 11 additions & 0 deletions packages/webview_flutter/webview_flutter_android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# webview\_flutter\_android

The Android implementation of [`webview_flutter`][1].

## Usage

This package is [endorsed][2], which means you can simply use `webview_flutter`
normally. This package will be automatically included in your app when you do.

[1]: https://pub.dev/packages/webview_flutter
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: ../../../analysis_options_legacy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
group 'io.flutter.plugins.webviewflutter'
version '1.0-SNAPSHOT'

buildscript {
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
}
}

rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}

apply plugin: 'com.android.library'

android {
compileSdkVersion 29

defaultConfig {
minSdkVersion 19
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

lintOptions {
disable 'InvalidPackage'
disable 'GradleDependency'
}

dependencies {
implementation 'androidx.annotation:annotation:1.0.0'
implementation 'androidx.webkit:webkit:1.0.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-inline:3.11.1'
testImplementation 'androidx.test:core:1.3.0'
}


testOptions {
unitTests.includeAndroidResources = true
unitTests.returnDefaultValues = true
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'webview_flutter'
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<manifest package="io.flutter.plugins.webviewflutter">
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// 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.

package io.flutter.plugins.webviewflutter;

import static android.hardware.display.DisplayManager.DisplayListener;

import android.annotation.TargetApi;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.ArrayList;

/**
* Works around an Android WebView bug by filtering some DisplayListener invocations.
*
* <p>Older Android WebView versions had assumed that when {@link DisplayListener#onDisplayChanged}
* is invoked, the display ID it is provided is of a valid display. However it turns out that when a
* display is removed Android may call onDisplayChanged with the ID of the removed display, in this
* case the Android WebView code tries to fetch and use the display with this ID and crashes with an
* NPE.
*
* <p>This issue was fixed in the Android WebView code in
* https://chromium-review.googlesource.com/517913 which is available starting WebView version
* 58.0.3029.125 however older webviews in the wild still have this issue.
*
* <p>Since Flutter removes virtual displays whenever a platform view is resized the webview crash
* is more likely to happen than other apps. And users were reporting this issue see:
* https://github.com/flutter/flutter/issues/30420
*
* <p>This class works around the webview bug by unregistering the WebView's DisplayListener, and
* instead registering its own DisplayListener which delegates the callbacks to the WebView's
* listener unless it's a onDisplayChanged for an invalid display.
*
* <p>I did not find a clean way to get a handle of the WebView's DisplayListener so I'm using
* reflection to fetch all registered listeners before and after initializing a webview. In the
* first initialization of a webview within the process the difference between the lists is the
* webview's display listener.
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
class DisplayListenerProxy {
private static final String TAG = "DisplayListenerProxy";

private ArrayList<DisplayListener> listenersBeforeWebView;

/** Should be called prior to the webview's initialization. */
void onPreWebViewInitialization(DisplayManager displayManager) {
listenersBeforeWebView = yoinkDisplayListeners(displayManager);
}

/** Should be called after the webview's initialization. */
void onPostWebViewInitialization(final DisplayManager displayManager) {
final ArrayList<DisplayListener> webViewListeners = yoinkDisplayListeners(displayManager);
// We recorded the list of listeners prior to initializing webview, any new listeners we see
// after initializing the webview are listeners added by the webview.
webViewListeners.removeAll(listenersBeforeWebView);

if (webViewListeners.isEmpty()) {
// The Android WebView registers a single display listener per process (even if there
// are multiple WebView instances) so this list is expected to be non-empty only the
// first time a webview is initialized.
// Note that in an add2app scenario if the application had instantiated a non Flutter
// WebView prior to instantiating the Flutter WebView we are not able to get a reference
// to the WebView's display listener and can't work around the bug.
//
// This means that webview resizes in add2app Flutter apps with a non Flutter WebView
// running on a system with a webview prior to 58.0.3029.125 may crash (the Android's
// behavior seems to be racy so it doesn't always happen).
return;
}

for (DisplayListener webViewListener : webViewListeners) {
// Note that while DisplayManager.unregisterDisplayListener throws when given an
// unregistered listener, this isn't an issue as the WebView code never calls
// unregisterDisplayListener.
displayManager.unregisterDisplayListener(webViewListener);

// We never explicitly unregister this listener as the webview's listener is never
// unregistered (it's released when the process is terminated).
displayManager.registerDisplayListener(
new DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
for (DisplayListener webViewListener : webViewListeners) {
webViewListener.onDisplayAdded(displayId);
}
}

@Override
public void onDisplayRemoved(int displayId) {
for (DisplayListener webViewListener : webViewListeners) {
webViewListener.onDisplayRemoved(displayId);
}
}

@Override
public void onDisplayChanged(int displayId) {
if (displayManager.getDisplay(displayId) == null) {
return;
}
for (DisplayListener webViewListener : webViewListeners) {
webViewListener.onDisplayChanged(displayId);
}
}
},
null);
}
}

@SuppressWarnings({"unchecked", "PrivateApi"})
private static ArrayList<DisplayListener> yoinkDisplayListeners(DisplayManager displayManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// We cannot use reflection on Android P, but it shouldn't matter as it shipped
// with WebView 66.0.3359.158 and the WebView version the bug this code is working around was
// fixed in 61.0.3116.0.
return new ArrayList<>();
}
try {
Field displayManagerGlobalField = DisplayManager.class.getDeclaredField("mGlobal");
displayManagerGlobalField.setAccessible(true);
Object displayManagerGlobal = displayManagerGlobalField.get(displayManager);
Field displayListenersField =
displayManagerGlobal.getClass().getDeclaredField("mDisplayListeners");
displayListenersField.setAccessible(true);
ArrayList<Object> delegates =
(ArrayList<Object>) displayListenersField.get(displayManagerGlobal);

Field listenerField = null;
ArrayList<DisplayManager.DisplayListener> listeners = new ArrayList<>();
for (Object delegate : delegates) {
if (listenerField == null) {
listenerField = delegate.getClass().getField("mListener");
listenerField.setAccessible(true);
}
DisplayManager.DisplayListener listener =
(DisplayManager.DisplayListener) listenerField.get(delegate);
listeners.add(listener);
}
return listeners;
} catch (NoSuchFieldException | IllegalAccessException e) {
Log.w(TAG, "Could not extract WebView's display listeners. " + e);
return new ArrayList<>();
}
}
}
Loading